MYC-deficiency impairs the development of effector/memory T lymphocytes

Authors :Mathis Nozais1*, Marie Loosveld1,2*, Saran Pankaew1, Clémence Grosjean1, Noémie Gentil1, Julie Quessada1, Cyrille Mionnet1, Delphine Potier1@ & Dominique Payet-Bornet1@

*These authors contributed equally: Mathis Nozais, Marie Loosveld; @ Corresponding authors: Dr Delphine Potier and Dr Dominique Payet-Bornet

Link to article : (TO come)

This code is made to be running on Seurat 301v2 Docker. Data and explanation about this code are available at : https://github.com/mathisnozais/MycPten

Any questions on this analysis, please contact Mathis Nozais or Delphine Potier (just delphine ? contact author)

to do before publish

#remettre ligne de code general identification (trop long a calcul pour les test de knit) + remettre pour cluster 13 deux premiere ligne list..

#cluster 3 DP small, 8,10,16
#11 refaire text marqueur
#refaire cluster 13 avec annot one note pour petit iddentif des pop
#DP blast put cell cycle umap ? dans le fichier myc_pten_paper --> report mycpten..cccaintegration_modif

#revoir titre partie en fonction du papier
#refaire docker en verifiant que tout les librairies necessaire sont dowloand dedans

#verif tout comm sont bein en anglais

#CD8 vs CD4 remettre les calcul de fin marker pour le final et pas le load fichier qui est la poru gagner du temps

#change output path
#loading final object obtain with Experiment_preprocessing
SAMPLE1 <- "replicate1"
SAMPLE2 <- "replicate2"

if(! file.exists(paste0(OUTPUT_PATH, "T-Seurat-merged_clean-subset",".Robj"))){
print("You should start with Experiment_preprocessing.Rmd or dowload our final object 'T-Seurat-merged_clean-subset.Robj' ")
do <- FALSE
}else{ 
print ("You are starting analysis of our final Seurat object")
load(paste0(OUTPUT_PATH, "T-Seurat-merged_clean-subset",".Robj"))
do <- TRUE
}

[1] “You are starting analysis of our final Seurat object”

Creating tissue subset

Separation of thymic and splenic subset based on the proportion of cells origin ## Thymus subset

Idents(T.Seurat) <- "HTO"
T.Seurat.thymus <- subset(T.Seurat, idents = c("Myc- PTEN- thymus","MYC- thymus","PTEN- thymus","WT thymus"))
a <- t(margin.table(table(T.Seurat.thymus@meta.data$HTO,T.Seurat.thymus@meta.data$integrated_snn_res.1.8),2))
T.Seurat.spleen <- subset(T.Seurat, idents = c("Myc- PTEN- spleen","MYC- spleen","PTEN- spleen","WT spleen"))
b <- t(margin.table(table(T.Seurat.spleen@meta.data$HTO,T.Seurat.spleen@meta.data$integrated_snn_res.1.8),2))
c <- t((a/(a+b)*100))

#Thymic populations
thymus.clusters <- rownames(as.data.frame(c[which(c[,1]>25),]))
Idents(T.Seurat.thymus) <- "integrated_snn_res.1.8"
T.Seurat.thymus <- subset(T.Seurat.thymus, idents = thymus.clusters)
DimPlot(T.Seurat.thymus)+ggtitle("Thymic subset")

Spleen subset

#Spleen populations
#as.data.frame(100-c[which(c[,1]<75),])
spleen.clusters <- rownames(as.data.frame(c[which(c[,1]<75),]))
Idents(T.Seurat.spleen) <- "integrated_snn_res.1.8"
T.Seurat.spleen <- subset(T.Seurat.spleen, idents = spleen.clusters)
DimPlot(T.Seurat.spleen)+ggtitle("Splenic subset")

Manual clustering

Based on several markers we are adjusting our clusterging, similar cluster are then annotate as one.

Thymic clusters :

#Look at differentiation markers on thymic clusters
DotPlot(T.Seurat.thymus, features = c("percent.mito","Bmf","Trp53inp1","Tox2","Cd5","Cd69","Cd27","Rag1","Rag2","Cd4","Cd8a","Cd8b1","Uchl3","Mki67","Cdk1","Ptcra","Il2ra","Cd34")) + scale_colour_gradient2(low = "steelblue", mid = "white", high = "red") + theme_dark(base_size = 14) + coord_flip()

#Regroup thymic clusters
#Similar cluster are annotate as one
Idents(T.Seurat.thymus) <- "integrated_snn_res.1.8"
T.Seurat.thymus@meta.data$manualclusters = "nothing"
T.Seurat.thymus@meta.data[WhichCells(T.Seurat.thymus, slot = "integrated_snn_res.1.8", idents = "22"),]$manualclusters = "22"
T.Seurat.thymus@meta.data[WhichCells(T.Seurat.thymus, slot = "integrated_snn_res.1.8", idents = "21"),]$manualclusters = "21"
T.Seurat.thymus@meta.data[WhichCells(T.Seurat.thymus, slot = "integrated_snn_res.1.8", idents = c("20","18","14")),]$manualclusters = "20,18,14"
T.Seurat.thymus@meta.data[WhichCells(T.Seurat.thymus, slot = "integrated_snn_res.1.8", idents = c("8","2","3","23")),]$manualclusters = "8,2,3,23"
T.Seurat.thymus@meta.data[WhichCells(T.Seurat.thymus, slot = "integrated_snn_res.1.8", idents = "6"),]$manualclusters = "6"
T.Seurat.thymus@meta.data[WhichCells(T.Seurat.thymus, slot = "integrated_snn_res.1.8", idents = "7"),]$manualclusters = "7"
T.Seurat.thymus@meta.data[WhichCells(T.Seurat.thymus, slot = "integrated_snn_res.1.8", idents = c("10","16")),]$manualclusters = "10,16"
T.Seurat.thymus@meta.data[WhichCells(T.Seurat.thymus, slot = "integrated_snn_res.1.8", idents = "17"),]$manualclusters = "17"

Splenic clusters :

#Look at differentiation markers on splenic clusters
DotPlot(T.Seurat.spleen, features = c("Aes","Anxa1","Ifng","Itgal","Foxp3","S1pr1","Sell","Ccr7","Trdc","Tcrg-C4","Tcrg-C2","Tcrg-C1","Trbc2","Trbc1","Trac","Cd8b1","Cd4")) + scale_colour_gradient2(low = "steelblue", mid = "white", high = "red") + theme_dark(base_size = 14) + coord_flip()

#Regroup splenic clusters
#Similar cluster are annotate as one
Idents(T.Seurat.spleen) <- "integrated_snn_res.1.8"
T.Seurat.spleen@meta.data$manualclusters = "nothing"
T.Seurat.spleen@meta.data[WhichCells(T.Seurat.spleen, slot = "integrated_snn_res.1.8", idents = "4"),]$manualclusters = "4"
T.Seurat.spleen@meta.data[WhichCells(T.Seurat.spleen, slot = "integrated_snn_res.1.8", idents = "1"),]$manualclusters = "1"
T.Seurat.spleen@meta.data[WhichCells(T.Seurat.spleen, slot = "integrated_snn_res.1.8", idents = "9"),]$manualclusters = "9"
T.Seurat.spleen@meta.data[WhichCells(T.Seurat.spleen, slot = "integrated_snn_res.1.8", idents = "12"),]$manualclusters = "12"
T.Seurat.spleen@meta.data[WhichCells(T.Seurat.spleen, slot = "integrated_snn_res.1.8", idents = "11"),]$manualclusters = "11"
T.Seurat.spleen@meta.data[WhichCells(T.Seurat.spleen, slot = "integrated_snn_res.1.8", idents = "19"),]$manualclusters = "19"
T.Seurat.spleen@meta.data[WhichCells(T.Seurat.spleen, slot = "integrated_snn_res.1.8", idents = "13"),]$manualclusters = "13"
T.Seurat.spleen@meta.data[WhichCells(T.Seurat.spleen, slot = "integrated_snn_res.1.8", idents = "17"),]$manualclusters = "17"
T.Seurat.spleen@meta.data[WhichCells(T.Seurat.spleen, slot = "integrated_snn_res.1.8", idents = c("10","16")),]$manualclusters = "10,16"
T.Seurat.spleen@meta.data[WhichCells(T.Seurat.spleen, slot = "integrated_snn_res.1.8", idents = "15"),]$manualclusters = "15"
T.Seurat.spleen@meta.data[WhichCells(T.Seurat.spleen, slot = "integrated_snn_res.1.8", idents = c("0","5")),]$manualclusters = "0,5"

Dot plot thymus

Setting thymic cluster order

Idents(T.Seurat.thymus) <- "manualclusters"
T.Seurat.thymus@active.ident <- factor(T.Seurat.thymus@active.ident,levels=c("22","21","20,18,14","8,2,3,23","7","6","10,16","17"))
DotPlot(T.Seurat.thymus, dot.scale = 8,features = c("percent.mito","Bmf","Trp53inp1","Tox2","Cd5","Cd69","Cd27","Rag1","Rag2","Cd4","Cd8a","Cd8b1","Mki67","Cdk1","Ptcra","Il2ra","Cd34")) + scale_colour_gradient2(low = "steelblue", mid = "white", high = "red") + coord_flip()+ theme(
  panel.background = element_rect(fill = "grey65",
                                size = 0.5, linetype = "solid"),
  panel.grid.major = element_line(size = 0.5, linetype = 'solid',
                                colour = "grey55"))

Dot plot spleen

Setting splenic cluster order

Idents(T.Seurat.spleen) <- "manualclusters"
T.Seurat.spleen@active.ident <- factor(T.Seurat.spleen@active.ident,levels=c("10,16","1","4","0,5","12","15","9","17","13","11","19"))
DotPlot(T.Seurat.spleen, dot.scale = 8, features= c("Foxp3","Aes","Anxa1","Gzma","Ccl5","Cxcr3","Sell","S1pr1","Ccr7","Trdc","Tcrg-C4","Tcrg-C2","Tcrg-C1","Trbc2","Trbc1","Trac","Cd8b1","Cd4")) + scale_colour_gradient2(low = "steelblue", mid = "white", high = "red") + theme(
  panel.background = element_rect(fill = "grey65",
                                size = 0.5, linetype = "solid"),
  panel.grid.major = element_line(size = 0.5, linetype = 'solid',
                                colour = "grey55")) + coord_flip()

Cluster Identification

General Identification markers

Idents(T.Seurat) <- "integrated_snn_res.1.8"
DefaultAssay(T.Seurat) <- "RNA"
#markerspleen <- FindAllMarkers(T.Seurat)

Detailed identification

Cluster 0

Idents(T.Seurat) <- "integrated_snn_res.1.8"
FeaturePlot(T.Seurat, features = c("adt_CD4","Sell","Cd8b1"),ncol = 3,cols = c("grey", "light blue","cyan3","cyan4","dodgerblue3","blue","mediumslateblue","purple","orchid3","red","brown","black"))

FeaturePlot(T.Seurat, features = c("Cd4","Cd8b1"),blend = T,
blend.threshold= 0.4,cols = c("grey", "light blue","cyan3","cyan4","dodgerblue3","blue","mediumslateblue","purple","orchid3","red","brown","black"))

Cluster 0 seems to contain naive SP4 cells (CD4+, Cd8- and CD62L-)

Cluster 1

FeaturePlot(T.Seurat, features = c("adt_CD4","Cd4","Cd8b1","Sell"),ncol = 4,cols = c("grey", "light blue","cyan3","cyan4","dodgerblue3","blue","mediumslateblue","purple","orchid3","red","brown","black"))

FeaturePlot(T.Seurat, features = c("Cd4","Cd8b1"),blend = T,
blend.threshold= 0.4,cols = c("grey", "light blue","cyan3","cyan4","dodgerblue3","blue","mediumslateblue","purple","orchid3","red","brown","black"))

Cluster 1 seems to contain CD8 naive T cells (CD4-, Cd8+ and CD62L-)

Cluster 2

FeaturePlot(T.Seurat, features = c("adt_CD4","Cd4","Cd8b1","Sell"),ncol = 4,cols = c("grey", "light blue","cyan3","cyan4","dodgerblue3","blue","mediumslateblue","purple","orchid3","red","brown","black"))

FeaturePlot(T.Seurat, features = c("Cd4","Cd8b1"),blend = T,
blend.threshold= 0.4,cols = c("grey", "light blue","cyan3","cyan4","dodgerblue3","blue","mediumslateblue","purple","orchid3","red","brown","black"))

Cluster 2 seems to contain DP cells (CD4+, CD8+, CD62L-)

Cluster 3

Cluster 4

FeaturePlot(T.Seurat, features = c("adt_CD4","Cd4","Cd8b1","Sell"),ncol = 4,cols = c("grey", "light blue","cyan3","cyan4","dodgerblue3","blue","mediumslateblue","purple","orchid3","red","brown","black"))

FeaturePlot(T.Seurat, features = c("Cd4","Cd8b1"),blend = T,
blend.threshold= 0.4,cols = c("grey", "light blue","cyan3","cyan4","dodgerblue3","blue","mediumslateblue","purple","orchid3","red","brown","black"))

Cluster 4 seems to contain CD8 naive T cells (CD4-, Cd8+, and CD62L-)

Cluster 5

FeaturePlot(T.Seurat, features = c("adt_CD4","Sell","Cd8b1"),ncol = 3,cols = c("grey", "light blue","cyan3","cyan4","dodgerblue3","blue","mediumslateblue","purple","orchid3","red","brown","black"))

FeaturePlot(T.Seurat, features = c("Cd4","Cd8b1"),blend = T,
blend.threshold= 0.4,cols = c("grey", "light blue","cyan3","cyan4","dodgerblue3","blue","mediumslateblue","purple","orchid3","red","brown","black"))

Cluster 5 seems to contain naive SP4 cells (CD4+, Cd8- and CD62L-)

Cluster 6

FeaturePlot(T.Seurat, features = c("percent.mito"),cols = c("grey", "light blue","cyan3","cyan4","dodgerblue3","blue","mediumslateblue","purple","orchid3","red","brown","black"), pt.size = 1)

Cluster 6 seems to contain dying cells

Cluster 7

FeaturePlot(T.Seurat, features = c("Cd69","Cd5","Satb1"),cols = c("grey", "light blue","cyan3","cyan4","dodgerblue3","blue","mediumslateblue","purple","orchid3","red","brown","black")) #marker of TCR activation 

Seems to contain cells going from DP to SP between thymus and spleen

Cluster 8

Cluster 9

FeaturePlot(T.Seurat, features = c("Cd4","adt_CD4"))

VlnPlot(T.Seurat.spleen, features = c("Sell","Ccr7","Il7r","Cxcr3"),ncol=2) # Cxcr3 high on effector

Seems to contain CD4 eff (Cd4+, Sell-, Ccr7-, Cd127-)

Cluster 10

Cluster 11

FeaturePlot(T.Seurat, features = c("Cd8b1","Sell","Ccl5","adt_CD4"),cols = c("grey", "light blue","cyan3","cyan4","dodgerblue3","blue","mediumslateblue","purple","orchid3","red","brown","black"))

FeaturePlot(T.Seurat, features = c("Trac","Trbc1","Trdc","Tcrg-C1"),cols = c("grey", "light blue","cyan3","cyan4","dodgerblue3","blue","mediumslateblue","purple","orchid3","red","brown","black"))

FeaturePlot(T.Seurat, features = c("Ly6c2","Nkg7"),cols = c("grey", "light blue","cyan3","cyan4","dodgerblue3","blue","mediumslateblue","purple","orchid3","red","brown","black"))

VlnPlot(T.Seurat.spleen, features = c("Sell","Ccr7","Il7r"))

Cluster 11 Seems to contain CD8 mem cells & seem to contain Tgd cells & Ly6c2+

Cluster 12

FeaturePlot(T.Seurat, features = c("adt_CD4","Sell","Cd8b1"),cols = c("grey", "light blue","cyan3","cyan4","dodgerblue3","blue","mediumslateblue","purple","orchid3","red","brown","black"))

#FeatureScatter(object = T.Seurat, feature1 = "adt_CD4", feature2 = "CD8", cells = colnames(subset(T.Seurat, idents = "0")), slot = "data")

Cluster 12 seems to contain naive SP4 cells (CD4+, Cd8- and CD62L -)

Cluster 13

plot1 <- DotPlot(cluster13, dot.scale = 10, features= c("Foxp3","Aes","Anxa1","Gzma","Ccl5","Cxcr3","Sell","S1pr1","Ccr7","Trdc","Tcrg-C4","Tcrg-C2","Tcrg-C1","Trbc2","Trbc1","Trac","Cd8b1","Cd4")) + scale_colour_gradient2(low = "steelblue", mid = "white", high = "red") + theme(
  panel.background = element_rect(fill = "grey65",
                                size = 0.5, linetype = "solid"),
  panel.grid.major = element_line(size = 0.5, linetype = 'solid',
                                colour = "grey55")) + coord_flip()
plot2 <- DotPlot(cluster13, dot.scale = 10, features= unique(top_genes_feature_plot$gene)) + scale_colour_gradient2(low = "steelblue", mid = "white", high = "red") + theme(
  panel.background = element_rect(fill = "grey65",
                                size = 0.5, linetype = "solid"),
  panel.grid.major = element_line(size = 0.5, linetype = 'solid',
                                colour = "grey55")) + coord_flip()
grid.arrange(plot1, plot2, ncol=2)

#table(cluster13@meta.data$integrated_snn_res.1)

This cluster is heterogeneous

Cluster 14

FeaturePlot(T.Seurat, features = c("adt_CD4","Cd4","Cd8b1"),cols = c("grey", "light blue","cyan3","cyan4","dodgerblue3","blue","mediumslateblue","purple","orchid3","red","brown","black"))

VlnPlot(T.Seurat, features = c("Pcna","Cdk1","Mki67"),ncol=2) #teichmann

Cluster 14 seems to be Dp blast

Cluster 15

FeaturePlot(T.Seurat, features = c("adt_CD4","Cd4","Foxp3","Il2ra"),cols = c("grey", "light blue","cyan3","cyan4","dodgerblue3","blue","mediumslateblue","purple","orchid3","red","brown","black"))

Cluster 15 seems to contain Treg (CD4+, Cd8-, Cd25+, Foxp3+)

Cluster 16

Cluster 17

FeaturePlot(T.Seurat, features = c("adt_CD4","Cd8b1","Trdc","Tcrg-C1"),cols = c("grey", "light blue","cyan3","cyan4","dodgerblue3","blue","mediumslateblue","purple","orchid3","red","brown","black"))

Cluster 17 seem to contain Tgd DN (CD4-, Cd8-, TCR D+, TCR G+)

Cluster 18

FeaturePlot(T.Seurat, features = c("adt_CD4","Cd4","Cd8b1"),cols = c("grey", "light blue","cyan3","cyan4","dodgerblue3","blue","mediumslateblue","purple","orchid3","red","brown","black"))

VlnPlot(T.Seurat, features = c("Pcna","Cdk1","Mki67"),ncol=2) #teichmann

Dp blast

Cluster 19

FeaturePlot(T.Seurat, features = c("Cd8b1","Sell","Ccl5","Gzma","Klrc1","Ifng","Zeb2","Ly6c2"),ncol = 3,cols = c("grey", "light blue","cyan3","cyan4","dodgerblue3","blue","mediumslateblue","purple","orchid3","red","brown","black"))

# Zeb2 terminally differentiated CTL
VlnPlot(T.Seurat.spleen, features = c("Sell","Ccr7","Il7r"))

Cluster 19 seemsto contain CD8 CTL (CD4-, Cd8+, Ccl5+, Sell-, ccr7-,cd127-) & Ly6c2+

Cluster 20

FeaturePlot(T.Seurat, features = c("adt_CD4","Cd4","Cd8b1"),cols = c("grey", "light blue","cyan3","cyan4","dodgerblue3","blue","mediumslateblue","purple","orchid3","red","brown","black"))

VlnPlot(T.Seurat, features = c("Pcna","Cdk1","Mki67"),ncol=2) #teichmann

Seems to be Dp blast

Cluster 21

FeaturePlot(T.Seurat, features = c("Cd8b1","adt_CD4"))

VlnPlot(T.Seurat, features = c("Cd8b1","adt_CD4"))

Cluster 21 seem to contain ISP cells (CD4-, Cd8+)

Cluster 22

FeaturePlot(T.Seurat, features = c("adt_CD4","Cd4","Cd8b1","Il2ra"),cols = c("grey", "light blue","cyan3","cyan4","dodgerblue3","blue","mediumslateblue","purple","orchid3","red","brown","black"))

Cluster 22 seems to contain DN T cells (CD4-, Cd8-, Cd25+)

Cluster 23

VlnPlot(T.Seurat, features = c("Cd8b1","adt_CD4"))

VlnPlot(T.Seurat, features = c("Rag1")) #on DP cells mostly (immgen), DP quicient or DP blast (Teichman)

Seems to be Dp small (Cd4+,Cd8+,Rag1+)

MYC vs WT

Radar plot

#check genotype proportion in each spleen clusters
par(mfrow=c(1,2))
df <- as.data.frame(as.data.frame.matrix(t(prop.table(table(T.Seurat.spleen@meta.data$HTO,T.Seurat.spleen@meta.data$manualclusters),1)*100)))
df$cluster = rownames(df)
df2<-as.data.frame(t(cbind(rep(60,11),rep(0,11),df)[,1:6]))
rownames(df2[1:2,]) <- c("60","0")

#order data frame
df2 <- df2[c("10,16","19","11","13","17","9","15","12","0,5","4","1")]

radarchart(df2, cglcol="grey", cglty=1 ,cglwd=0.8, vlcex=0.8, pcol=c("#FF99FF","coral1","cyan3","chartreuse3") , plwd=3, plty=1 ,caxislabels=paste(seq(from = 0,to = 60,by = 15),"%"), axislabcol = "grey40", axistype = 0)

#check genotype proportion in each thymic cluster
df <-  as.data.frame(as.data.frame.matrix(t(prop.table(table(T.Seurat.thymus@meta.data$HTO,T.Seurat.thymus@meta.data$manualclusters),1)*100)))
df$cluster = rownames(df)
df2<-as.data.frame(t(cbind(rep(65,8),rep(0,8),df)[,1:6]))
rownames(df2[1:2,]) <- c("65","0")

#order
df2 <- df2[c("22","17","10,16","6","7","8,2,3,23","20,18,14","21")]


radarchart(df2, cglcol="grey", cglty=1,caxislabels=paste(seq(0,70,17.5),"%"), axistype = 0,axislabcol="grey40", cglwd=0.8, vlcex=0.8, pcol=c("#FF99FF","coral1","cyan3","chartreuse3") , plwd=3, plty=1 )

#par(mfrow = c(1,1))

Proportion bar plot

#thymic proportions
datathym <- data.frame(prop.table(t(prop.table(table(T.Seurat.thymus@meta.data$HTO,T.Seurat.thymus@meta.data$manualclusters),1)),1)*100)
#order cluster level
datathym$Var1 <- factor(datathym$Var1, levels = c("22","21","20,18,14","8,2,3,23","7","6","10,16","17"))

cellnumber <- data.frame(colSums(table(T.Seurat.thymus@meta.data$HTO,T.Seurat.thymus@meta.data$manualclusters)) )
cellnumber$cluster <- rownames(cellnumber)
row_order <- c("22","21","20,18,14","8,2,3,23","6","7","17","10,16")
cellnumber <- cellnumber[row_order,]

Cluster <- datathym$Var1
HTO <- datathym$Var2
Percentage <- datathym$Freq
text <- cellnumber$colSums.table.T.Seurat.thymus.meta.data.HTO..T.Seurat.thymus.meta.data.manualclusters..

cols <- c("Myc- PTEN- thymus" = "#FF99FF", "MYC- thymus" = "coral1", "PTEN- thymus" = "cyan3", "WT thymus" = "chartreuse3")

ggplot(datathym, aes(fill=HTO, y=Percentage, x=Cluster)) + 
    geom_bar(position="stack", stat="identity", width=0.7)+
   xlab("Thymic Clusters")+ylab("Percentage")+ theme(legend.position="bottom")+ scale_fill_manual(values =cols, labels=c("Myc Pten","Myc","Pten","WT"))+theme_light()+geom_hline(yintercept=c(25,50,75), linetype="dashed", color = "grey60")+ annotate("text", x = c(1,2,3,4,5,6,7,8), y=103, label = c(paste0(text)))

#splenic proportions
Idents(T.Seurat.spleen) <- "manualclusters"
T.Seurat.spleenbar <- subset(T.Seurat.spleen,  idents = c("0,5","9","1","11","19")) #to only keep cluster needed for the plot
data3 <- data.frame(prop.table(t(prop.table(table(T.Seurat.spleenbar@meta.data$HTO,T.Seurat.spleenbar@meta.data$manualclusters),1)),1)*100)

#order cluster level
data3$Var1 <- factor(data3$Var1, levels = c("0,5","9","1","11","19"))

cellnumber <- data.frame(colSums(table(T.Seurat.spleen@meta.data$HTO,T.Seurat.spleen@meta.data$manualclusters)) )
cellnumber$cluster <- rownames(cellnumber)
row_order <-c("0,5","9","1","11","19")
cellnumber <- cellnumber[row_order,]

Cluster <- data3$Var1
HTO <- data3$Var2
Percentage <- data3$Freq
text <- cellnumber$colSums.table.T.Seurat.spleen.meta.data.HTO..T.Seurat.spleen.meta.data.manualclusters..
# Stacked bar plot
cols <- c("Myc- PTEN- spleen" = "#FF99FF", "MYC- spleen" = "coral1", "PTEN- spleen" = "cyan3", "WT spleen" = "chartreuse3")

ggplot(data3, aes(fill=HTO, y=Percentage, x=Cluster)) + 
    geom_bar(position="stack", stat="identity", width=0.7)+
   xlab("Splenic Clusters")+ylab("Percentage")+ theme(legend.position="bottom")+scale_fill_manual(values =cols, labels=c("Myc Pten","Myc","Pten","WT")) +theme_light()+geom_hline(yintercept=c(25,50,75), linetype="dashed", color = "grey60")+ annotate("text", x = c(1,2,3,4,5), y=103, label = c(text))

Differential Gene Expression

CD8

Idents(T.Seurat) <- "integrated_snn_res.1.8"
#DGE between our two CD8 naive clusters
dgecd8_data <- FindMarkers(T.Seurat, ident.1 = "1", ident.2 = "4",logfc.threshold=0)

# bar plot
#add abs value to table
dgecd8_data$abs <- abs(dgecd8_data$avg_logFC) 

dgecd8_data$genename <- rownames(dgecd8_data)
# Select markers for plotting on a Heatmap 
markers.use=subset(dgecd8_data, p_val_adj<1e-50 & abs>0.20)
dfcd8markers <-markers.use[order(markers.use$avg_logFC),]

dfcd8markers$genename <- factor(dfcd8markers$genename, levels = dfcd8markers$genename[order(dfcd8markers$avg_logFC)])
dfcd8markers$logpval <- log10(dfcd8markers$p_val_adj)
ggplot(dfcd8markers, aes(x = dfcd8markers$genename, y = dfcd8markers$avg_logFC, fill = logpval)) +   # Fill column
                              geom_bar(stat = "identity", width = .6) +   # draw the bars
                              ylim(-1.2,1.2)+
                              labs(title="DGE - Cluster 1 vs 4 (Cd8 naive)",y ="Log fold change", x = "Genes differentially expressed") +
                              theme_tufte() +  # Tufte theme from ggfortify
                              theme(plot.title = element_text(hjust = .5),axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1), 
                                    axis.ticks = element_blank()) +
                               scale_fill_gradient2(low='red', mid='orange', high='blue',midpoint = -120, breaks=c(-52,-120,-200),labels=c("-50","-120","-200"))+coord_flip() # Flip axes

CD4

define proportion of genotype in CD4 naive clusters :

T.Seurat.spleen@meta.data$manualHTO = "nothing"
Idents(T.Seurat.spleen) <- "MULTI_ID"
T.Seurat.spleen@meta.data[WhichCells(T.Seurat.spleen, slot = "MULTI_ID", idents = c("Spleen-ctrl","Spleen-P")),]$manualHTO = "Spleen-ctrl&P"
T.Seurat.spleen@meta.data[WhichCells(T.Seurat.spleen, slot = "MULTI_ID", idents = c("Spleen-M","Spleen-MP")),]$manualHTO = "Spleen-M&MP"

tab <- (prop.table(t(prop.table(table(T.Seurat.spleen@meta.data$integrated_snn_res.1.8,T.Seurat.spleen@meta.data$manualHTO),1)),2)*100)

In our CD4 naive clusters (0,5 and 12) the one with most cells from M&MP is 0 and the one with most cells from ctrl&P is 12

Idents(T.Seurat) <- "integrated_snn_res.1.8"
#DGE between 0 and 12
dgecd4_data <- FindMarkers(T.Seurat, ident.1 = "0", ident.2 = "12",logfc.threshold=0)
# bar plot
#add abs value to table
dgecd4_data$abs <- abs(dgecd4_data$avg_logFC) 

dgecd4_data$genename <- rownames(dgecd4_data)
# Select markers for plotting on a Heatmap 
markers.use=subset(dgecd4_data,p_val_adj<1e-10 & abs>0.2)
dfcd4markers <-markers.use[order(markers.use$avg_logFC),]

dfcd4markers$genename <- factor(dfcd4markers$genename, levels = dfcd4markers$genename[order(dfcd4markers$avg_logFC)])
dfcd4markers$logpval <- log10(dfcd4markers$p_val_adj)
ggplot(dfcd4markers, aes(x = dfcd4markers$genename, y = dfcd4markers$avg_logFC, fill = logpval)) +   # Fill column
                              geom_bar(stat = "identity", width = .6) +   # draw the bars
                              ylim(-1.2,1.2)+
                              labs(title="DGE - Cluster 0 vs 12 (Cd4 naive)",y ="Log fold change", x = "Genes differentially expressed") +
                              theme_tufte() +  # Tufte theme from ggfortify
                              theme(plot.title = element_text(hjust = .5),axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1), 
                                    axis.ticks = element_blank()) +
                               scale_fill_gradient2(low='red', mid='orange', high='blue',midpoint = -40, breaks=c(-12,-40,-57),labels=c("-10","-40","-60"))+ coord_flip() # Flip axes

Functional profil analysis (Gene Ontology)

Idents(T.Seurat) <- "integrated_snn_res.1.8"

# get all gene name express in our cells as background
background <- T.Seurat@assays$RNA@meta.features
backgroundrow <- rownames(background)

Naive CD8 T cells

#DGE between our two CD8 naive clusters
#dgecd8_data <- FindMarkers(T.Seurat, ident.1 = "1", ident.2 = "4",logfc.threshold=0)
#upreg_cd8 <- subset(dgecd8_data, avg_logFC>0)
#downreg_cd8 <- subset(dgecd8_data, avg_logFC<0.2 & p_val_adj<1e-50)
#genecomprow <- rownames(downreg_cd8)


#### TO SUPPRESS FOR FINAL
#write.table(genecomprow,file="/home/nozaism/Workspace/01_These/01_Project/Myc_Pten_Paper/cluster1v4.txt",sep="\t",quote=F)
genecomprow <- read.table("/home/nozaism/Workspace/01_These/01_Project/Myc_Pten_Paper/cluster1v4.txt", sep = "\t")
genecomprow$x = as.character(genecomprow$x)
genecomprow <- genecomprow[,1]

CPenrich <- enrichGO(gene= genecomprow, OrgDb = 'org.Mm.eg.db', ont="BP",keyType = "SYMBOL",universe = backgroundrow) # org.Mm.eg.db genome mouse
#head (CPenrich)
dotplot(CPenrich, showCategory=15,color = "p.adjust",x="count") #+ coord_flip()+theme(axis.text.x = element_text(angle = 90, hjust = 1))

emapplot(CPenrich, showCategory = 50)

Naive CD4 T cells

#DGE between our two most control and Myd del CD4 naive clusters
#dgecd4_data <- FindMarkers(T.Seurat, ident.1 = "0", ident.2 = "12",logfc.threshold=0)
#downreg_cd4 <- subset(dgecd4_data, avg_logFC<0& p_val_adj<1e-20)
#genecomprow <- rownames(downreg_cd4)


#### TO SUPPRESS FOR FINAL
#write.table(genecomprow,file="/home/nozaism/Workspace/01_These/01_Project/Myc_Pten_Paper/cluster0vs12.txt",sep="\t",quote=F)
genecomprow <- read.table("/home/nozaism/Workspace/01_These/01_Project/Myc_Pten_Paper/cluster0vs12.txt", sep = "\t")
genecomprow$x = as.character(genecomprow$x)
genecomprow <- genecomprow[,1]
####


CPenrich <- enrichGO(gene= genecomprow, OrgDb = 'org.Mm.eg.db', ont="BP",keyType = "SYMBOL",universe = backgroundrow) # org.Mm.eg.db genome mouse
dotplot(CPenrich, showCategory=15,color = "p.adjust",x="count")+ scale_y_discrete(labels=function(x)str_wrap(x, width=40))

eYFP negative investigation

Deciphering what are our eYFP negative cells on effector and memory CD8 T cells

Heatmap :

# On cluster 11 - cd8 memory
C11Ctrl <-rownames(T.Seurat.spleen@meta.data[T.Seurat.spleen@meta.data$MULTI_ID == "Spleen-ctrl" & T.Seurat.spleen@meta.data$integrated_snn_res.1.8 == "11",])
mC11Ctrl <- mean(T.Seurat.spleen@assays$RNA@data["eYFP",C11Ctrl])
C11Pt <- rownames(T.Seurat.spleen@meta.data[T.Seurat.spleen@meta.data$MULTI_ID == "Spleen-P" & T.Seurat.spleen@meta.data$integrated_snn_res.1.8 == "11",])
mC11Pt <- mean(T.Seurat.spleen@assays$RNA@data["eYFP",C11Pt])
C11MP <- rownames(T.Seurat.spleen@meta.data[T.Seurat.spleen@meta.data$MULTI_ID == "Spleen-MP" & T.Seurat.spleen@meta.data$integrated_snn_res.1.8 == "11",])
mC11MP <- mean(T.Seurat.spleen@assays$RNA@data["eYFP",C11MP])
C11M <- rownames(T.Seurat.spleen@meta.data[T.Seurat.spleen@meta.data$MULTI_ID == "Spleen-M" & T.Seurat.spleen@meta.data$integrated_snn_res.1.8 == "11",])
mC11M <- mean(T.Seurat.spleen@assays$RNA@data["eYFP",C11M])
#on cluster 19 - cd8 eff term
C19Ctrl <-rownames(T.Seurat.spleen@meta.data[T.Seurat.spleen@meta.data$MULTI_ID == "Spleen-ctrl" & T.Seurat.spleen@meta.data$integrated_snn_res.1.8 == "19",])
mC19Ctrl <- mean(T.Seurat.spleen@assays$RNA@data["eYFP",C19Ctrl])
C19Pt <- rownames(T.Seurat.spleen@meta.data[T.Seurat.spleen@meta.data$MULTI_ID == "Spleen-P" & T.Seurat.spleen@meta.data$integrated_snn_res.1.8 == "19",])
mC19Pt <- mean(T.Seurat.spleen@assays$RNA@data["eYFP",C19Pt])
C19MP <- rownames(T.Seurat.spleen@meta.data[T.Seurat.spleen@meta.data$MULTI_ID == "Spleen-MP" & T.Seurat.spleen@meta.data$integrated_snn_res.1.8 == "19",])
mC19MP <- mean(T.Seurat.spleen@assays$RNA@data["eYFP",C19MP])
C19M <- rownames(T.Seurat.spleen@meta.data[T.Seurat.spleen@meta.data$MULTI_ID == "Spleen-M" & T.Seurat.spleen@meta.data$integrated_snn_res.1.8 == "19",])
mC19M <- mean(T.Seurat.spleen@assays$RNA@data["eYFP",C19M])
#on cluster 1
C1Ctrl <-rownames(T.Seurat.spleen@meta.data[T.Seurat.spleen@meta.data$MULTI_ID == "Spleen-ctrl" & T.Seurat.spleen@meta.data$integrated_snn_res.1.8 == "1",])
mC1Ctrl <- mean(T.Seurat.spleen@assays$RNA@data["eYFP",C1Ctrl])
C1Pt <- rownames(T.Seurat.spleen@meta.data[T.Seurat.spleen@meta.data$MULTI_ID == "Spleen-P" & T.Seurat.spleen@meta.data$integrated_snn_res.1.8 == "1",])
mC1Pt <- mean(T.Seurat.spleen@assays$RNA@data["eYFP",C1Pt])
C1MP <- rownames(T.Seurat.spleen@meta.data[T.Seurat.spleen@meta.data$MULTI_ID == "Spleen-MP" & T.Seurat.spleen@meta.data$integrated_snn_res.1.8 == "1",])
mC1MP <- mean(T.Seurat.spleen@assays$RNA@data["eYFP",C1MP])
C1M <- rownames(T.Seurat.spleen@meta.data[T.Seurat.spleen@meta.data$MULTI_ID == "Spleen-M" & T.Seurat.spleen@meta.data$integrated_snn_res.1.8 == "1",])
mC1M <- mean(T.Seurat.spleen@assays$RNA@data["eYFP",C1M])


l1 <- c("1","1","1","1","11","11","11","11","19","19","19","19")
l2 <- c("Ctrl","Pten","Myc","MycPten","Ctrl","Pten","Myc","MycPten","Ctrl","Pten","Myc","MycPten")
l3 <- c(mC1Ctrl,mC1Pt,mC1M,mC1MP,mC11Ctrl,mC11Pt,mC11M,mC11MP,mC19Ctrl,mC19Pt,mC19M,mC19MP)

tableauYFP <- data.frame(Cluster = l1, Genotypes =l2) 
tableauYFP <- cbind(tableauYFP,Values = l3)


tableauYFP$Cluster <- factor(tableauYFP$Cluster,levels = c("1","11","19"))
tableauYFP$Genotypes <- factor(tableauYFP$Genotypes,levels = c("MycPten","Myc","Pten","Ctrl"))
ggplot(tableauYFP, aes(x = Cluster, Genotypes)) +
        geom_tile(aes(fill = Values)) +
        scale_fill_gradient2( mid='yellow', high='red',limits=c(0,max(tableauYFP$Values)))+ theme_classic(base_size=20)

eYFP neagtive are coming from Myc and Myc Pten del mice

#DOT plot eyFP and TGD on CD8 effector and memory
Idents(T.Seurat.spleen) <- "integrated_snn_res.1.8"
CD8sub <- subset(T.Seurat.spleen, idents = c("11","19","13"))
Idents(CD8sub) <- "MULTI_ID"
CD8sub@active.ident <- factor(CD8sub@active.ident,levels=c("Spleen-M","Spleen-MP","Spleen-ctrl","Spleen-P"))
#levels(CD8sub)
DotPlot(CD8sub, dot.scale = 8,features = c("Tcrg-C1","Trdc","Trbc2","Trac","eYFP") ) + scale_colour_gradient2(low = "steelblue", mid = "white", high = "red")+ ggtitle("CD8 memory and effector clusters")

eyFP negative are coming from Myc and Myc Pten del mice and are Tgd cells.

Session Info

sessionInfo()
## R version 3.5.3 (2019-03-11)
## Platform: x86_64-pc-linux-gnu (64-bit)
## Running under: Ubuntu 16.04.5 LTS
## 
## Matrix products: default
## BLAS/LAPACK: /usr/lib/libopenblasp-r0.2.18.so
## 
## locale:
##  [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
##  [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8    
##  [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=C             
##  [7] LC_PAPER=en_US.UTF-8       LC_NAME=C                 
##  [9] LC_ADDRESS=C               LC_TELEPHONE=C            
## [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       
## 
## attached base packages:
## [1] parallel  stats4    stats     graphics  grDevices utils     datasets 
## [8] methods   base     
## 
## other attached packages:
##  [1] org.Mm.eg.db_3.7.0     AnnotationDbi_1.44.0   IRanges_2.16.0        
##  [4] S4Vectors_0.20.1       Biobase_2.42.0         BiocGenerics_0.28.0   
##  [7] knitr_1.23             RColorBrewer_1.1-2     magrittr_1.5          
## [10] dplyr_0.8.1            stringr_1.4.0          ggthemes_4.2.0        
## [13] clusterProfiler_3.10.1 enrichplot_1.2.0       fmsb_0.6.3            
## [16] gridExtra_2.3          kableExtra_1.1.0       plotly_4.9.0          
## [19] ggplot2_3.1.1          Seurat_3.0.1          
## 
## loaded via a namespace (and not attached):
##   [1] fastmatch_1.1-0     plyr_1.8.4          igraph_1.2.4.1     
##   [4] lazyeval_0.2.2      splines_3.5.3       BiocParallel_1.16.6
##   [7] listenv_0.7.0       urltools_1.7.3      digest_0.6.19      
##  [10] htmltools_0.3.6     GOSemSim_2.8.0      viridis_0.5.1      
##  [13] GO.db_3.7.0         gdata_2.18.0        memoise_1.1.0      
##  [16] cluster_2.0.9       ROCR_1.0-7          globals_0.12.4     
##  [19] readr_1.3.1         R.utils_2.8.0       prettyunits_1.0.2  
##  [22] colorspace_1.4-1    blob_1.1.1          rvest_0.3.4        
##  [25] ggrepel_0.8.1       xfun_0.7            crayon_1.3.4       
##  [28] jsonlite_1.6        survival_2.44-1.1   zoo_1.8-5          
##  [31] ape_5.3             glue_1.3.1          polyclip_1.10-0    
##  [34] gtable_0.3.0        webshot_0.5.1       UpSetR_1.4.0       
##  [37] future.apply_1.2.0  scales_1.0.0        DOSE_3.8.2         
##  [40] DBI_1.0.0           bibtex_0.4.2        Rcpp_1.0.1         
##  [43] metap_1.1           viridisLite_0.3.0   progress_1.2.2     
##  [46] gridGraphics_0.5-1  reticulate_1.12     bit_1.1-14         
##  [49] europepmc_0.4       rsvd_1.0.0          SDMTools_1.1-221.1 
##  [52] tsne_0.1-3          htmlwidgets_1.3     httr_1.4.0         
##  [55] fgsea_1.8.0         gplots_3.0.1.1      ica_1.0-2          
##  [58] pkgconfig_2.0.2     R.methodsS3_1.7.1   farver_1.1.0       
##  [61] ggplotify_0.0.5     tidyselect_0.2.5    labeling_0.3       
##  [64] rlang_0.3.4         reshape2_1.4.3      munsell_0.5.0      
##  [67] tools_3.5.3         RSQLite_2.1.1       ggridges_0.5.1     
##  [70] evaluate_0.13       yaml_2.2.0          npsurv_0.4-0       
##  [73] bit64_0.9-7         fitdistrplus_1.0-14 caTools_1.17.1.2   
##  [76] purrr_0.3.2         RANN_2.6.1          ggraph_1.0.2       
##  [79] pbapply_1.4-0       future_1.13.0       nlme_3.1-140       
##  [82] R.oo_1.22.0         DO.db_2.9           xml2_1.2.0         
##  [85] compiler_3.5.3      rstudioapi_0.10     png_0.1-7          
##  [88] lsei_1.2-0          tibble_2.1.1        tweenr_1.0.1       
##  [91] stringi_1.4.3       lattice_0.20-38     Matrix_1.2-17      
##  [94] pillar_1.4.0        BiocManager_1.30.4  Rdpack_0.11-0      
##  [97] triebeard_0.3.0     lmtest_0.9-37       data.table_1.12.2  
## [100] cowplot_0.9.4       bitops_1.0-6        irlba_2.3.3        
## [103] gbRd_0.4-11         qvalue_2.14.1       R6_2.4.0           
## [106] KernSmooth_2.23-15  codetools_0.2-16    MASS_7.3-51.4      
## [109] gtools_3.8.1        assertthat_0.2.1    withr_2.1.2        
## [112] sctransform_0.2.0   hms_0.4.2           grid_3.5.3         
## [115] tidyr_0.8.3         rmarkdown_1.12      rvcheck_0.1.8      
## [118] Rtsne_0.15          ggforce_0.2.2       base64enc_0.1-3
LS0tCnRpdGxlOiAiRXhwZXJpbWVudF9hbmFseXNpcyIKYXV0aG9yOiAiRGVscGhpbmUgUG90aWVyIC8gTWF0aGlzIE5vemFpcyAvIFNhcmFuIFBhbmthZXciCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKZWRpdG9yX29wdGlvbnM6IAogIGNodW5rX291dHB1dF90eXBlOiBjb25zb2xlCi0tLQoKPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KLm1haW4tY29udGFpbmVyIHsKICBtYXgtd2lkdGg6IDE4MDBweDsKICBtYXJnaW4tbGVmdDogYXV0bzsKICBtYXJnaW4tcmlnaHQ6IGF1dG87Cn0KPC9zdHlsZT4KCmBgYHtyIGdsb2JhbC1vcHRpb25zLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQod2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRSxmaWcuYWxpZ24gPSAnY2VudGVyJykKYGBgCgojIE1ZQy1kZWZpY2llbmN5IGltcGFpcnMgdGhlIGRldmVsb3BtZW50IG9mIGVmZmVjdG9yL21lbW9yeSBUIGx5bXBob2N5dGVzCgpBdXRob3JzIDpNYXRoaXMgTm96YWlzMVwqLCBNYXJpZSBMb29zdmVsZDEsMlwqLCBTYXJhbiBQYW5rYWV3MSwgQ2zDqW1lbmNlIEdyb3NqZWFuMSwgTm/DqW1pZSBHZW50aWwxLCBKdWxpZSBRdWVzc2FkYTEsIEN5cmlsbGUgTWlvbm5ldDEsIERlbHBoaW5lIFBvdGllcjFAICYgRG9taW5pcXVlIFBheWV0LUJvcm5ldDFACgoqVGhlc2UgYXV0aG9ycyBjb250cmlidXRlZCBlcXVhbGx5OiBNYXRoaXMgTm96YWlzLCBNYXJpZSBMb29zdmVsZDsgQCBDb3JyZXNwb25kaW5nIGF1dGhvcnM6IERyIERlbHBoaW5lIFBvdGllciBhbmQgRHIgRG9taW5pcXVlIFBheWV0LUJvcm5ldAoKTGluayB0byBhcnRpY2xlIDogKFRPIGNvbWUpCgpUaGlzIGNvZGUgaXMgbWFkZSB0byBiZSBydW5uaW5nIG9uIFNldXJhdCAzMDF2MiBEb2NrZXIuIERhdGEgYW5kIGV4cGxhbmF0aW9uIGFib3V0IHRoaXMgY29kZSBhcmUgYXZhaWxhYmxlIGF0IDogaHR0cHM6Ly9naXRodWIuY29tL21hdGhpc25vemFpcy9NeWNQdGVuCgpBbnkgcXVlc3Rpb25zIG9uIHRoaXMgYW5hbHlzaXMsIHBsZWFzZSBjb250YWN0IE1hdGhpcyBOb3phaXMgb3IgRGVscGhpbmUgUG90aWVyIChqdXN0IGRlbHBoaW5lID8gY29udGFjdCBhdXRob3IpCgoKI3RvIGRvIGJlZm9yZSBwdWJsaXNoCmBgYHtyfQojcmVtZXR0cmUgbGlnbmUgZGUgY29kZSBnZW5lcmFsIGlkZW50aWZpY2F0aW9uICh0cm9wIGxvbmcgYSBjYWxjdWwgcG91ciBsZXMgdGVzdCBkZSBrbml0KSArIHJlbWV0dHJlIHBvdXIgY2x1c3RlciAxMyBkZXV4IHByZW1pZXJlIGxpZ25lIGxpc3QuLgoKI2NsdXN0ZXIgMyBEUCBzbWFsbCwgOCwxMCwxNgojMTEgcmVmYWlyZSB0ZXh0IG1hcnF1ZXVyCiNyZWZhaXJlIGNsdXN0ZXIgMTMgYXZlYyBhbm5vdCBvbmUgbm90ZSBwb3VyIHBldGl0IGlkZGVudGlmIGRlcyBwb3AKI0RQIGJsYXN0IHB1dCBjZWxsIGN5Y2xlIHVtYXAgPyBkYW5zIGxlIGZpY2hpZXIgbXljX3B0ZW5fcGFwZXIgLS0+IHJlcG9ydCBteWNwdGVuLi5jY2NhaW50ZWdyYXRpb25fbW9kaWYKCiNyZXZvaXIgdGl0cmUgcGFydGllIGVuIGZvbmN0aW9uIGR1IHBhcGllcgojcmVmYWlyZSBkb2NrZXIgZW4gdmVyaWZpYW50IHF1ZSB0b3V0IGxlcyBsaWJyYWlyaWVzIG5lY2Vzc2FpcmUgc29udCBkb3dsb2FuZCBkZWRhbnMKCiN2ZXJpZiB0b3V0IGNvbW0gc29udCBiZWluIGVuIGFuZ2xhaXMKCiNDRDggdnMgQ0Q0IHJlbWV0dHJlIGxlcyBjYWxjdWwgZGUgZmluIG1hcmtlciBwb3VyIGxlIGZpbmFsIGV0IHBhcyBsZSBsb2FkIGZpY2hpZXIgcXVpIGVzdCBsYSBwb3J1IGdhZ25lciBkdSB0ZW1wcwoKI2NoYW5nZSBvdXRwdXQgcGF0aAoKYGBgCgoKCmBgYHtyIGVudl9sb2FkaW5nLCBpbmNsdWRlPUZBTFNFfQojIExvYWQgcGFja2FnZXMsIGRhdGEgYW5kIGZ1bmN0aW9ucwpsaWJyYXJ5KFNldXJhdCkKbGlicmFyeShwbG90bHkpCmxpYnJhcnkoa2FibGVFeHRyYSkKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGdyaWRFeHRyYSkKbGlicmFyeShmbXNiKQpsaWJyYXJ5KGVucmljaHBsb3QpCmxpYnJhcnkoY2x1c3RlclByb2ZpbGVyKQojbGlicmFyeShnZ3JlcGVsKQojbGlicmFyeSgidGlkeXIiKQpsaWJyYXJ5KGdndGhlbWVzKQojbGlicmFyeShzY2FsZXMpCmxpYnJhcnkoc3RyaW5ncikKCiNQYXRoIHRvIHRoZSBhbmFseXNpcyBmb2xkZXIKV09SS1NQQUNFIDwtICIvaG9tZS9ub3phaXNtL1dvcmtzcGFjZS8wMV9UaGVzZS8wMV9Qcm9qZWN0L015Y19QdGVuX1BhcGVyL015Y19yZXBvLyIKIyBQYXRoIHRvIHRoZSBmb2xkZXIgY29udGFpbmluZyBzY3JpcHRzIHVzZWQgaW4gdGhlIGFuYWx5c2lzCkNXRCA8LSAiL2hvbWUvbm96YWlzbS9Xb3Jrc3BhY2UvRnVuY3Rpb25fZGVscGhpbmUvIiAKIyBMb2FkIHRoZSBSIHNjcmlwdHMgY29udGFpbmluZyB0aGUgZnVuY3Rpb25zIHVzZWQgaW4gdGhlIGFuYWx5c2lzCnNvdXJjZShwYXN0ZShDV0QsICJXb3JrZmxvd19mdW5jdGlvbnNfUzMuUiIsIHNlcD0iLyIpKQojICBQYXRoIHRvIHRoZSBmb2xkZXIgdGhhdCB3aWxsIGNvbnRhaW4gb3V0cHV0IG9iamVjdHMKT1VUUFVUX1BBVEggPC0gKCIvaG9tZS9ub3phaXNtL1dvcmtzcGFjZS8wMV9UaGVzZS8wMV9Qcm9qZWN0L015Y19QdGVuX1BhcGVyL091dHB1dF9yZXBvLyIpCiMgU2V0IHRoZSByYW5kb20gbnVtYmVyIHNlZWQKc2V0LnNlZWQoMTIzNCkKIyBSZXNvbHV0aW9uIHBhcmFtZXRlciBmb3IgU2V1cmF0IGNsdXN0ZXJpbmcKUkVTT0xVVElPTiA8LSAxCmBgYAoKYGBge3IscmVzdWx0cz0nYXNpcyd9CiNsb2FkaW5nIGZpbmFsIG9iamVjdCBvYnRhaW4gd2l0aCBFeHBlcmltZW50X3ByZXByb2Nlc3NpbmcKU0FNUExFMSA8LSAicmVwbGljYXRlMSIKU0FNUExFMiA8LSAicmVwbGljYXRlMiIKCmlmKCEgZmlsZS5leGlzdHMocGFzdGUwKE9VVFBVVF9QQVRILCAiVC1TZXVyYXQtbWVyZ2VkX2NsZWFuLXN1YnNldCIsIi5Sb2JqIikpKXsKcHJpbnQoIllvdSBzaG91bGQgc3RhcnQgd2l0aCBFeHBlcmltZW50X3ByZXByb2Nlc3NpbmcuUm1kIG9yIGRvd2xvYWQgb3VyIGZpbmFsIG9iamVjdCAnVC1TZXVyYXQtbWVyZ2VkX2NsZWFuLXN1YnNldC5Sb2JqJyAiKQpkbyA8LSBGQUxTRQp9ZWxzZXsgCnByaW50ICgiWW91IGFyZSBzdGFydGluZyBhbmFseXNpcyBvZiBvdXIgZmluYWwgU2V1cmF0IG9iamVjdCIpCmxvYWQocGFzdGUwKE9VVFBVVF9QQVRILCAiVC1TZXVyYXQtbWVyZ2VkX2NsZWFuLXN1YnNldCIsIi5Sb2JqIikpCmRvIDwtIFRSVUUKfQoKYGBgCgoKYGBge2FzaXMsIGV2YWw9KGRvID09IFRSVUUgKSwgZWNobz1UUlVFfQojIENyZWF0aW5nIHRpc3N1ZSBzdWJzZXQKU2VwYXJhdGlvbiBvZiB0aHltaWMgYW5kIHNwbGVuaWMgc3Vic2V0IGJhc2VkIG9uIHRoZSBwcm9wb3J0aW9uIG9mIGNlbGxzIG9yaWdpbiAKIyMgVGh5bXVzIHN1YnNldApgYGAKCmBgYHtyLGV2YWw9KGRvID09IFRSVUUgKX0KSWRlbnRzKFQuU2V1cmF0KSA8LSAiSFRPIgpULlNldXJhdC50aHltdXMgPC0gc3Vic2V0KFQuU2V1cmF0LCBpZGVudHMgPSBjKCJNeWMtIFBURU4tIHRoeW11cyIsIk1ZQy0gdGh5bXVzIiwiUFRFTi0gdGh5bXVzIiwiV1QgdGh5bXVzIikpCmEgPC0gdChtYXJnaW4udGFibGUodGFibGUoVC5TZXVyYXQudGh5bXVzQG1ldGEuZGF0YSRIVE8sVC5TZXVyYXQudGh5bXVzQG1ldGEuZGF0YSRpbnRlZ3JhdGVkX3Nubl9yZXMuMS44KSwyKSkKVC5TZXVyYXQuc3BsZWVuIDwtIHN1YnNldChULlNldXJhdCwgaWRlbnRzID0gYygiTXljLSBQVEVOLSBzcGxlZW4iLCJNWUMtIHNwbGVlbiIsIlBURU4tIHNwbGVlbiIsIldUIHNwbGVlbiIpKQpiIDwtIHQobWFyZ2luLnRhYmxlKHRhYmxlKFQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGEkSFRPLFQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGEkaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCksMikpCmMgPC0gdCgoYS8oYStiKSoxMDApKQoKI1RoeW1pYyBwb3B1bGF0aW9ucwp0aHltdXMuY2x1c3RlcnMgPC0gcm93bmFtZXMoYXMuZGF0YS5mcmFtZShjW3doaWNoKGNbLDFdPjI1KSxdKSkKSWRlbnRzKFQuU2V1cmF0LnRoeW11cykgPC0gImludGVncmF0ZWRfc25uX3Jlcy4xLjgiClQuU2V1cmF0LnRoeW11cyA8LSBzdWJzZXQoVC5TZXVyYXQudGh5bXVzLCBpZGVudHMgPSB0aHltdXMuY2x1c3RlcnMpCkRpbVBsb3QoVC5TZXVyYXQudGh5bXVzKStnZ3RpdGxlKCJUaHltaWMgc3Vic2V0IikKYGBgCgpgYGB7YXNpcywgZXZhbD0oZG8gPT0gVFJVRSApLCBlY2hvPVRSVUV9CiMjIFNwbGVlbiBzdWJzZXQKYGBgCgoKYGBge3J9CiNTcGxlZW4gcG9wdWxhdGlvbnMKI2FzLmRhdGEuZnJhbWUoMTAwLWNbd2hpY2goY1ssMV08NzUpLF0pCnNwbGVlbi5jbHVzdGVycyA8LSByb3duYW1lcyhhcy5kYXRhLmZyYW1lKGNbd2hpY2goY1ssMV08NzUpLF0pKQpJZGVudHMoVC5TZXVyYXQuc3BsZWVuKSA8LSAiaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCIKVC5TZXVyYXQuc3BsZWVuIDwtIHN1YnNldChULlNldXJhdC5zcGxlZW4sIGlkZW50cyA9IHNwbGVlbi5jbHVzdGVycykKRGltUGxvdChULlNldXJhdC5zcGxlZW4pK2dndGl0bGUoIlNwbGVuaWMgc3Vic2V0IikKYGBgCgojIE1hbnVhbCBjbHVzdGVyaW5nCkJhc2VkIG9uIHNldmVyYWwgbWFya2VycyB3ZSBhcmUgYWRqdXN0aW5nIG91ciBjbHVzdGVyZ2luZywgc2ltaWxhciBjbHVzdGVyIGFyZSB0aGVuIGFubm90YXRlIGFzIG9uZS4KClRoeW1pYyBjbHVzdGVycyA6CmBgYHtyfQojTG9vayBhdCBkaWZmZXJlbnRpYXRpb24gbWFya2VycyBvbiB0aHltaWMgY2x1c3RlcnMKRG90UGxvdChULlNldXJhdC50aHltdXMsIGZlYXR1cmVzID0gYygicGVyY2VudC5taXRvIiwiQm1mIiwiVHJwNTNpbnAxIiwiVG94MiIsIkNkNSIsIkNkNjkiLCJDZDI3IiwiUmFnMSIsIlJhZzIiLCJDZDQiLCJDZDhhIiwiQ2Q4YjEiLCJVY2hsMyIsIk1raTY3IiwiQ2RrMSIsIlB0Y3JhIiwiSWwycmEiLCJDZDM0IikpICsgc2NhbGVfY29sb3VyX2dyYWRpZW50Mihsb3cgPSAic3RlZWxibHVlIiwgbWlkID0gIndoaXRlIiwgaGlnaCA9ICJyZWQiKSArIHRoZW1lX2RhcmsoYmFzZV9zaXplID0gMTQpICsgY29vcmRfZmxpcCgpCgojUmVncm91cCB0aHltaWMgY2x1c3RlcnMKI1NpbWlsYXIgY2x1c3RlciBhcmUgYW5ub3RhdGUgYXMgb25lCklkZW50cyhULlNldXJhdC50aHltdXMpIDwtICJpbnRlZ3JhdGVkX3Nubl9yZXMuMS44IgpULlNldXJhdC50aHltdXNAbWV0YS5kYXRhJG1hbnVhbGNsdXN0ZXJzID0gIm5vdGhpbmciClQuU2V1cmF0LnRoeW11c0BtZXRhLmRhdGFbV2hpY2hDZWxscyhULlNldXJhdC50aHltdXMsIHNsb3QgPSAiaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCIsIGlkZW50cyA9ICIyMiIpLF0kbWFudWFsY2x1c3RlcnMgPSAiMjIiClQuU2V1cmF0LnRoeW11c0BtZXRhLmRhdGFbV2hpY2hDZWxscyhULlNldXJhdC50aHltdXMsIHNsb3QgPSAiaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCIsIGlkZW50cyA9ICIyMSIpLF0kbWFudWFsY2x1c3RlcnMgPSAiMjEiClQuU2V1cmF0LnRoeW11c0BtZXRhLmRhdGFbV2hpY2hDZWxscyhULlNldXJhdC50aHltdXMsIHNsb3QgPSAiaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCIsIGlkZW50cyA9IGMoIjIwIiwiMTgiLCIxNCIpKSxdJG1hbnVhbGNsdXN0ZXJzID0gIjIwLDE4LDE0IgpULlNldXJhdC50aHltdXNAbWV0YS5kYXRhW1doaWNoQ2VsbHMoVC5TZXVyYXQudGh5bXVzLCBzbG90ID0gImludGVncmF0ZWRfc25uX3Jlcy4xLjgiLCBpZGVudHMgPSBjKCI4IiwiMiIsIjMiLCIyMyIpKSxdJG1hbnVhbGNsdXN0ZXJzID0gIjgsMiwzLDIzIgpULlNldXJhdC50aHltdXNAbWV0YS5kYXRhW1doaWNoQ2VsbHMoVC5TZXVyYXQudGh5bXVzLCBzbG90ID0gImludGVncmF0ZWRfc25uX3Jlcy4xLjgiLCBpZGVudHMgPSAiNiIpLF0kbWFudWFsY2x1c3RlcnMgPSAiNiIKVC5TZXVyYXQudGh5bXVzQG1ldGEuZGF0YVtXaGljaENlbGxzKFQuU2V1cmF0LnRoeW11cywgc2xvdCA9ICJpbnRlZ3JhdGVkX3Nubl9yZXMuMS44IiwgaWRlbnRzID0gIjciKSxdJG1hbnVhbGNsdXN0ZXJzID0gIjciClQuU2V1cmF0LnRoeW11c0BtZXRhLmRhdGFbV2hpY2hDZWxscyhULlNldXJhdC50aHltdXMsIHNsb3QgPSAiaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCIsIGlkZW50cyA9IGMoIjEwIiwiMTYiKSksXSRtYW51YWxjbHVzdGVycyA9ICIxMCwxNiIKVC5TZXVyYXQudGh5bXVzQG1ldGEuZGF0YVtXaGljaENlbGxzKFQuU2V1cmF0LnRoeW11cywgc2xvdCA9ICJpbnRlZ3JhdGVkX3Nubl9yZXMuMS44IiwgaWRlbnRzID0gIjE3IiksXSRtYW51YWxjbHVzdGVycyA9ICIxNyIKYGBgCgpTcGxlbmljIGNsdXN0ZXJzIDoKYGBge3J9CgojTG9vayBhdCBkaWZmZXJlbnRpYXRpb24gbWFya2VycyBvbiBzcGxlbmljIGNsdXN0ZXJzCkRvdFBsb3QoVC5TZXVyYXQuc3BsZWVuLCBmZWF0dXJlcyA9IGMoIkFlcyIsIkFueGExIiwiSWZuZyIsIkl0Z2FsIiwiRm94cDMiLCJTMXByMSIsIlNlbGwiLCJDY3I3IiwiVHJkYyIsIlRjcmctQzQiLCJUY3JnLUMyIiwiVGNyZy1DMSIsIlRyYmMyIiwiVHJiYzEiLCJUcmFjIiwiQ2Q4YjEiLCJDZDQiKSkgKyBzY2FsZV9jb2xvdXJfZ3JhZGllbnQyKGxvdyA9ICJzdGVlbGJsdWUiLCBtaWQgPSAid2hpdGUiLCBoaWdoID0gInJlZCIpICsgdGhlbWVfZGFyayhiYXNlX3NpemUgPSAxNCkgKyBjb29yZF9mbGlwKCkKCiNSZWdyb3VwIHNwbGVuaWMgY2x1c3RlcnMKI1NpbWlsYXIgY2x1c3RlciBhcmUgYW5ub3RhdGUgYXMgb25lCklkZW50cyhULlNldXJhdC5zcGxlZW4pIDwtICJpbnRlZ3JhdGVkX3Nubl9yZXMuMS44IgpULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhJG1hbnVhbGNsdXN0ZXJzID0gIm5vdGhpbmciClQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGFbV2hpY2hDZWxscyhULlNldXJhdC5zcGxlZW4sIHNsb3QgPSAiaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCIsIGlkZW50cyA9ICI0IiksXSRtYW51YWxjbHVzdGVycyA9ICI0IgpULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhW1doaWNoQ2VsbHMoVC5TZXVyYXQuc3BsZWVuLCBzbG90ID0gImludGVncmF0ZWRfc25uX3Jlcy4xLjgiLCBpZGVudHMgPSAiMSIpLF0kbWFudWFsY2x1c3RlcnMgPSAiMSIKVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YVtXaGljaENlbGxzKFQuU2V1cmF0LnNwbGVlbiwgc2xvdCA9ICJpbnRlZ3JhdGVkX3Nubl9yZXMuMS44IiwgaWRlbnRzID0gIjkiKSxdJG1hbnVhbGNsdXN0ZXJzID0gIjkiClQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGFbV2hpY2hDZWxscyhULlNldXJhdC5zcGxlZW4sIHNsb3QgPSAiaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCIsIGlkZW50cyA9ICIxMiIpLF0kbWFudWFsY2x1c3RlcnMgPSAiMTIiClQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGFbV2hpY2hDZWxscyhULlNldXJhdC5zcGxlZW4sIHNsb3QgPSAiaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCIsIGlkZW50cyA9ICIxMSIpLF0kbWFudWFsY2x1c3RlcnMgPSAiMTEiClQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGFbV2hpY2hDZWxscyhULlNldXJhdC5zcGxlZW4sIHNsb3QgPSAiaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCIsIGlkZW50cyA9ICIxOSIpLF0kbWFudWFsY2x1c3RlcnMgPSAiMTkiClQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGFbV2hpY2hDZWxscyhULlNldXJhdC5zcGxlZW4sIHNsb3QgPSAiaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCIsIGlkZW50cyA9ICIxMyIpLF0kbWFudWFsY2x1c3RlcnMgPSAiMTMiClQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGFbV2hpY2hDZWxscyhULlNldXJhdC5zcGxlZW4sIHNsb3QgPSAiaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCIsIGlkZW50cyA9ICIxNyIpLF0kbWFudWFsY2x1c3RlcnMgPSAiMTciClQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGFbV2hpY2hDZWxscyhULlNldXJhdC5zcGxlZW4sIHNsb3QgPSAiaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCIsIGlkZW50cyA9IGMoIjEwIiwiMTYiKSksXSRtYW51YWxjbHVzdGVycyA9ICIxMCwxNiIKVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YVtXaGljaENlbGxzKFQuU2V1cmF0LnNwbGVlbiwgc2xvdCA9ICJpbnRlZ3JhdGVkX3Nubl9yZXMuMS44IiwgaWRlbnRzID0gIjE1IiksXSRtYW51YWxjbHVzdGVycyA9ICIxNSIKVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YVtXaGljaENlbGxzKFQuU2V1cmF0LnNwbGVlbiwgc2xvdCA9ICJpbnRlZ3JhdGVkX3Nubl9yZXMuMS44IiwgaWRlbnRzID0gYygiMCIsIjUiKSksXSRtYW51YWxjbHVzdGVycyA9ICIwLDUiCmBgYAoKCiMjIERvdCBwbG90IHRoeW11cwoKU2V0dGluZyB0aHltaWMgY2x1c3RlciBvcmRlciAKYGBge3J9CklkZW50cyhULlNldXJhdC50aHltdXMpIDwtICJtYW51YWxjbHVzdGVycyIKVC5TZXVyYXQudGh5bXVzQGFjdGl2ZS5pZGVudCA8LSBmYWN0b3IoVC5TZXVyYXQudGh5bXVzQGFjdGl2ZS5pZGVudCxsZXZlbHM9YygiMjIiLCIyMSIsIjIwLDE4LDE0IiwiOCwyLDMsMjMiLCI3IiwiNiIsIjEwLDE2IiwiMTciKSkKYGBgCgpgYGB7cixmaWcud2lkdGggPSAxMCwgZmlnLmhlaWdodCA9IDZ9CkRvdFBsb3QoVC5TZXVyYXQudGh5bXVzLCBkb3Quc2NhbGUgPSA4LGZlYXR1cmVzID0gYygicGVyY2VudC5taXRvIiwiQm1mIiwiVHJwNTNpbnAxIiwiVG94MiIsIkNkNSIsIkNkNjkiLCJDZDI3IiwiUmFnMSIsIlJhZzIiLCJDZDQiLCJDZDhhIiwiQ2Q4YjEiLCJNa2k2NyIsIkNkazEiLCJQdGNyYSIsIklsMnJhIiwiQ2QzNCIpKSArIHNjYWxlX2NvbG91cl9ncmFkaWVudDIobG93ID0gInN0ZWVsYmx1ZSIsIG1pZCA9ICJ3aGl0ZSIsIGhpZ2ggPSAicmVkIikgKyBjb29yZF9mbGlwKCkrIHRoZW1lKAogIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJncmV5NjUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemUgPSAwLjUsIGxpbmV0eXBlID0gInNvbGlkIiksCiAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShzaXplID0gMC41LCBsaW5ldHlwZSA9ICdzb2xpZCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3VyID0gImdyZXk1NSIpKQpgYGAKCiMjIERvdCBwbG90IHNwbGVlbgoKU2V0dGluZyBzcGxlbmljIGNsdXN0ZXIgb3JkZXIgCmBgYHtyfQpJZGVudHMoVC5TZXVyYXQuc3BsZWVuKSA8LSAibWFudWFsY2x1c3RlcnMiClQuU2V1cmF0LnNwbGVlbkBhY3RpdmUuaWRlbnQgPC0gZmFjdG9yKFQuU2V1cmF0LnNwbGVlbkBhY3RpdmUuaWRlbnQsbGV2ZWxzPWMoIjEwLDE2IiwiMSIsIjQiLCIwLDUiLCIxMiIsIjE1IiwiOSIsIjE3IiwiMTMiLCIxMSIsIjE5IikpCmBgYAoKYGBge3J9CkRvdFBsb3QoVC5TZXVyYXQuc3BsZWVuLCBkb3Quc2NhbGUgPSA4LCBmZWF0dXJlcz0gYygiRm94cDMiLCJBZXMiLCJBbnhhMSIsIkd6bWEiLCJDY2w1IiwiQ3hjcjMiLCJTZWxsIiwiUzFwcjEiLCJDY3I3IiwiVHJkYyIsIlRjcmctQzQiLCJUY3JnLUMyIiwiVGNyZy1DMSIsIlRyYmMyIiwiVHJiYzEiLCJUcmFjIiwiQ2Q4YjEiLCJDZDQiKSkgKyBzY2FsZV9jb2xvdXJfZ3JhZGllbnQyKGxvdyA9ICJzdGVlbGJsdWUiLCBtaWQgPSAid2hpdGUiLCBoaWdoID0gInJlZCIpICsgdGhlbWUoCiAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gImdyZXk2NSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZSA9IDAuNSwgbGluZXR5cGUgPSAic29saWQiKSwKICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKHNpemUgPSAwLjUsIGxpbmV0eXBlID0gJ3NvbGlkJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvdXIgPSAiZ3JleTU1IikpICsgY29vcmRfZmxpcCgpCmBgYAoKCiMgQ2x1c3RlciBJZGVudGlmaWNhdGlvbgojIyBHZW5lcmFsIElkZW50aWZpY2F0aW9uIG1hcmtlcnMKYGBge3J9CklkZW50cyhULlNldXJhdCkgPC0gImludGVncmF0ZWRfc25uX3Jlcy4xLjgiCkRlZmF1bHRBc3NheShULlNldXJhdCkgPC0gIlJOQSIKI21hcmtlcnNwbGVlbiA8LSBGaW5kQWxsTWFya2VycyhULlNldXJhdCkKYGBgCgojIyBEZXRhaWxlZCBpZGVudGlmaWNhdGlvbiB7LnRhYnNldCAudGFic2V0LWZhZGV9CiMjIyBDbHVzdGVyIDAKYGBge3IsZmlnLndpZHRoID0gMTUsIGZpZy5oZWlnaHQgPSA0fQpJZGVudHMoVC5TZXVyYXQpIDwtICJpbnRlZ3JhdGVkX3Nubl9yZXMuMS44IgpGZWF0dXJlUGxvdChULlNldXJhdCwgZmVhdHVyZXMgPSBjKCJhZHRfQ0Q0IiwiU2VsbCIsIkNkOGIxIiksbmNvbCA9IDMsY29scyA9IGMoImdyZXkiLCAibGlnaHQgYmx1ZSIsImN5YW4zIiwiY3lhbjQiLCJkb2RnZXJibHVlMyIsImJsdWUiLCJtZWRpdW1zbGF0ZWJsdWUiLCJwdXJwbGUiLCJvcmNoaWQzIiwicmVkIiwiYnJvd24iLCJibGFjayIpKQpgYGAKCmBgYHtyLGZpZy53aWR0aCA9IDIwLCBmaWcuaGVpZ2h0ID0gNH0KRmVhdHVyZVBsb3QoVC5TZXVyYXQsIGZlYXR1cmVzID0gYygiQ2Q0IiwiQ2Q4YjEiKSxibGVuZCA9IFQsCmJsZW5kLnRocmVzaG9sZD0gMC40LGNvbHMgPSBjKCJncmV5IiwgImxpZ2h0IGJsdWUiLCJjeWFuMyIsImN5YW40IiwiZG9kZ2VyYmx1ZTMiLCJibHVlIiwibWVkaXVtc2xhdGVibHVlIiwicHVycGxlIiwib3JjaGlkMyIsInJlZCIsImJyb3duIiwiYmxhY2siKSkKYGBgCgpDbHVzdGVyIDAgc2VlbXMgdG8gY29udGFpbiBuYWl2ZSBTUDQgY2VsbHMgKENENCssIENkOC0gYW5kIENENjJMLSkKCiMjIyBDbHVzdGVyIDEKYGBge3IsZmlnLndpZHRoID0gMjAsIGZpZy5oZWlnaHQgPSA0fQpGZWF0dXJlUGxvdChULlNldXJhdCwgZmVhdHVyZXMgPSBjKCJhZHRfQ0Q0IiwiQ2Q0IiwiQ2Q4YjEiLCJTZWxsIiksbmNvbCA9IDQsY29scyA9IGMoImdyZXkiLCAibGlnaHQgYmx1ZSIsImN5YW4zIiwiY3lhbjQiLCJkb2RnZXJibHVlMyIsImJsdWUiLCJtZWRpdW1zbGF0ZWJsdWUiLCJwdXJwbGUiLCJvcmNoaWQzIiwicmVkIiwiYnJvd24iLCJibGFjayIpKQpgYGAKCmBgYHtyLGZpZy53aWR0aCA9IDIwLCBmaWcuaGVpZ2h0ID0gNH0KRmVhdHVyZVBsb3QoVC5TZXVyYXQsIGZlYXR1cmVzID0gYygiQ2Q0IiwiQ2Q4YjEiKSxibGVuZCA9IFQsCmJsZW5kLnRocmVzaG9sZD0gMC40LGNvbHMgPSBjKCJncmV5IiwgImxpZ2h0IGJsdWUiLCJjeWFuMyIsImN5YW40IiwiZG9kZ2VyYmx1ZTMiLCJibHVlIiwibWVkaXVtc2xhdGVibHVlIiwicHVycGxlIiwib3JjaGlkMyIsInJlZCIsImJyb3duIiwiYmxhY2siKSkKYGBgCgpDbHVzdGVyIDEgc2VlbXMgdG8gY29udGFpbiBDRDggbmFpdmUgVCBjZWxscyAoQ0Q0LSwgQ2Q4KyBhbmQgQ0Q2MkwtKQoKIyMjIENsdXN0ZXIgMgpgYGB7cixmaWcud2lkdGggPSAyMCwgZmlnLmhlaWdodCA9IDR9CkZlYXR1cmVQbG90KFQuU2V1cmF0LCBmZWF0dXJlcyA9IGMoImFkdF9DRDQiLCJDZDQiLCJDZDhiMSIsIlNlbGwiKSxuY29sID0gNCxjb2xzID0gYygiZ3JleSIsICJsaWdodCBibHVlIiwiY3lhbjMiLCJjeWFuNCIsImRvZGdlcmJsdWUzIiwiYmx1ZSIsIm1lZGl1bXNsYXRlYmx1ZSIsInB1cnBsZSIsIm9yY2hpZDMiLCJyZWQiLCJicm93biIsImJsYWNrIikpCmBgYAoKYGBge3IsZmlnLndpZHRoID0gMjAsIGZpZy5oZWlnaHQgPSA0fQpGZWF0dXJlUGxvdChULlNldXJhdCwgZmVhdHVyZXMgPSBjKCJDZDQiLCJDZDhiMSIpLGJsZW5kID0gVCwKYmxlbmQudGhyZXNob2xkPSAwLjQsY29scyA9IGMoImdyZXkiLCAibGlnaHQgYmx1ZSIsImN5YW4zIiwiY3lhbjQiLCJkb2RnZXJibHVlMyIsImJsdWUiLCJtZWRpdW1zbGF0ZWJsdWUiLCJwdXJwbGUiLCJvcmNoaWQzIiwicmVkIiwiYnJvd24iLCJibGFjayIpKQpgYGAKCgpDbHVzdGVyIDIgc2VlbXMgdG8gY29udGFpbiBEUCBjZWxscyAoQ0Q0KywgQ0Q4KywgQ0Q2MkwtKQoKIyMjIENsdXN0ZXIgMwoKIyMjIENsdXN0ZXIgNApgYGB7cixmaWcud2lkdGggPSAyMCwgZmlnLmhlaWdodCA9IDR9CkZlYXR1cmVQbG90KFQuU2V1cmF0LCBmZWF0dXJlcyA9IGMoImFkdF9DRDQiLCJDZDQiLCJDZDhiMSIsIlNlbGwiKSxuY29sID0gNCxjb2xzID0gYygiZ3JleSIsICJsaWdodCBibHVlIiwiY3lhbjMiLCJjeWFuNCIsImRvZGdlcmJsdWUzIiwiYmx1ZSIsIm1lZGl1bXNsYXRlYmx1ZSIsInB1cnBsZSIsIm9yY2hpZDMiLCJyZWQiLCJicm93biIsImJsYWNrIikpCmBgYAoKYGBge3IsZmlnLndpZHRoID0gMjAsIGZpZy5oZWlnaHQgPSA0fQpGZWF0dXJlUGxvdChULlNldXJhdCwgZmVhdHVyZXMgPSBjKCJDZDQiLCJDZDhiMSIpLGJsZW5kID0gVCwKYmxlbmQudGhyZXNob2xkPSAwLjQsY29scyA9IGMoImdyZXkiLCAibGlnaHQgYmx1ZSIsImN5YW4zIiwiY3lhbjQiLCJkb2RnZXJibHVlMyIsImJsdWUiLCJtZWRpdW1zbGF0ZWJsdWUiLCJwdXJwbGUiLCJvcmNoaWQzIiwicmVkIiwiYnJvd24iLCJibGFjayIpKQpgYGAKCkNsdXN0ZXIgNCBzZWVtcyB0byBjb250YWluIENEOCBuYWl2ZSBUIGNlbGxzIChDRDQtLCBDZDgrLCBhbmQgQ0Q2MkwtKQoKIyMjIENsdXN0ZXIgNQpgYGB7cixmaWcud2lkdGggPSAxNSwgZmlnLmhlaWdodCA9IDR9CkZlYXR1cmVQbG90KFQuU2V1cmF0LCBmZWF0dXJlcyA9IGMoImFkdF9DRDQiLCJTZWxsIiwiQ2Q4YjEiKSxuY29sID0gMyxjb2xzID0gYygiZ3JleSIsICJsaWdodCBibHVlIiwiY3lhbjMiLCJjeWFuNCIsImRvZGdlcmJsdWUzIiwiYmx1ZSIsIm1lZGl1bXNsYXRlYmx1ZSIsInB1cnBsZSIsIm9yY2hpZDMiLCJyZWQiLCJicm93biIsImJsYWNrIikpCmBgYAoKYGBge3IsIGZpZy53aWR0aCA9IDIwLCBmaWcuaGVpZ2h0ID0gNH0KRmVhdHVyZVBsb3QoVC5TZXVyYXQsIGZlYXR1cmVzID0gYygiQ2Q0IiwiQ2Q4YjEiKSxibGVuZCA9IFQsCmJsZW5kLnRocmVzaG9sZD0gMC40LGNvbHMgPSBjKCJncmV5IiwgImxpZ2h0IGJsdWUiLCJjeWFuMyIsImN5YW40IiwiZG9kZ2VyYmx1ZTMiLCJibHVlIiwibWVkaXVtc2xhdGVibHVlIiwicHVycGxlIiwib3JjaGlkMyIsInJlZCIsImJyb3duIiwiYmxhY2siKSkKYGBgCgpDbHVzdGVyIDUgc2VlbXMgdG8gY29udGFpbiBuYWl2ZSBTUDQgY2VsbHMgKENENCssIENkOC0gYW5kIENENjJMLSkKCiMjIyBDbHVzdGVyIDYKYGBge3J9CkZlYXR1cmVQbG90KFQuU2V1cmF0LCBmZWF0dXJlcyA9IGMoInBlcmNlbnQubWl0byIpLGNvbHMgPSBjKCJncmV5IiwgImxpZ2h0IGJsdWUiLCJjeWFuMyIsImN5YW40IiwiZG9kZ2VyYmx1ZTMiLCJibHVlIiwibWVkaXVtc2xhdGVibHVlIiwicHVycGxlIiwib3JjaGlkMyIsInJlZCIsImJyb3duIiwiYmxhY2siKSwgcHQuc2l6ZSA9IDEpCmBgYApDbHVzdGVyIDYgc2VlbXMgdG8gY29udGFpbiBkeWluZyBjZWxscwoKIyMjIENsdXN0ZXIgNwpgYGB7cixmaWcud2lkdGggPSAxMCwgZmlnLmhlaWdodCA9IDh9CkZlYXR1cmVQbG90KFQuU2V1cmF0LCBmZWF0dXJlcyA9IGMoIkNkNjkiLCJDZDUiLCJTYXRiMSIpLGNvbHMgPSBjKCJncmV5IiwgImxpZ2h0IGJsdWUiLCJjeWFuMyIsImN5YW40IiwiZG9kZ2VyYmx1ZTMiLCJibHVlIiwibWVkaXVtc2xhdGVibHVlIiwicHVycGxlIiwib3JjaGlkMyIsInJlZCIsImJyb3duIiwiYmxhY2siKSkgI21hcmtlciBvZiBUQ1IgYWN0aXZhdGlvbiAKYGBgClNlZW1zIHRvIGNvbnRhaW4gY2VsbHMgZ29pbmcgZnJvbSBEUCB0byBTUCBiZXR3ZWVuIHRoeW11cyBhbmQgc3BsZWVuCgojIyMgQ2x1c3RlciA4CgojIyMgQ2x1c3RlciA5CmBgYHtyLCBmaWcud2lkdGggPSAxMCwgZmlnLmhlaWdodCA9IDR9CkZlYXR1cmVQbG90KFQuU2V1cmF0LCBmZWF0dXJlcyA9IGMoIkNkNCIsImFkdF9DRDQiKSkKYGBgCgpgYGB7ciwgZmlnLndpZHRoID0gMjAsIGZpZy5oZWlnaHQgPSAxMn0KVmxuUGxvdChULlNldXJhdC5zcGxlZW4sIGZlYXR1cmVzID0gYygiU2VsbCIsIkNjcjciLCJJbDdyIiwiQ3hjcjMiKSxuY29sPTIpICMgQ3hjcjMgaGlnaCBvbiBlZmZlY3RvcgpgYGAKU2VlbXMgdG8gY29udGFpbiBDRDQgZWZmIChDZDQrLCBTZWxsLSwgQ2NyNy0sIENkMTI3LSkKCiMjIyBDbHVzdGVyIDEwCmBgYHtyIGNsc3V0ZXIxMH0KCmBgYAoKIyMjIENsdXN0ZXIgMTEKYGBge3IgY2x1c3RlcjExLGZpZy53aWR0aCA9IDEwLCBmaWcuaGVpZ2h0ID0gOH0KRmVhdHVyZVBsb3QoVC5TZXVyYXQsIGZlYXR1cmVzID0gYygiQ2Q4YjEiLCJTZWxsIiwiQ2NsNSIsImFkdF9DRDQiKSxjb2xzID0gYygiZ3JleSIsICJsaWdodCBibHVlIiwiY3lhbjMiLCJjeWFuNCIsImRvZGdlcmJsdWUzIiwiYmx1ZSIsIm1lZGl1bXNsYXRlYmx1ZSIsInB1cnBsZSIsIm9yY2hpZDMiLCJyZWQiLCJicm93biIsImJsYWNrIikpCgpGZWF0dXJlUGxvdChULlNldXJhdCwgZmVhdHVyZXMgPSBjKCJUcmFjIiwiVHJiYzEiLCJUcmRjIiwiVGNyZy1DMSIpLGNvbHMgPSBjKCJncmV5IiwgImxpZ2h0IGJsdWUiLCJjeWFuMyIsImN5YW40IiwiZG9kZ2VyYmx1ZTMiLCJibHVlIiwibWVkaXVtc2xhdGVibHVlIiwicHVycGxlIiwib3JjaGlkMyIsInJlZCIsImJyb3duIiwiYmxhY2siKSkKYGBgCgpgYGB7cixmaWcud2lkdGggPSAxMCwgZmlnLmhlaWdodCA9IDR9CkZlYXR1cmVQbG90KFQuU2V1cmF0LCBmZWF0dXJlcyA9IGMoIkx5NmMyIiwiTmtnNyIpLGNvbHMgPSBjKCJncmV5IiwgImxpZ2h0IGJsdWUiLCJjeWFuMyIsImN5YW40IiwiZG9kZ2VyYmx1ZTMiLCJibHVlIiwibWVkaXVtc2xhdGVibHVlIiwicHVycGxlIiwib3JjaGlkMyIsInJlZCIsImJyb3duIiwiYmxhY2siKSkKYGBgCgpgYGB7cixmaWcud2lkdGggPSAyMCwgZmlnLmhlaWdodCA9IDZ9ClZsblBsb3QoVC5TZXVyYXQuc3BsZWVuLCBmZWF0dXJlcyA9IGMoIlNlbGwiLCJDY3I3IiwiSWw3ciIpKQpgYGAKCkNsdXN0ZXIgMTEgU2VlbXMgdG8gY29udGFpbiBDRDggbWVtIGNlbGxzICYgc2VlbSB0byBjb250YWluIFRnZCBjZWxscyAmIEx5NmMyKwoKIyMjIENsdXN0ZXIgMTIKYGBge3IgY2x1c3RlcjEyLGZpZy53aWR0aCA9IDEwLCBmaWcuaGVpZ2h0ID0gOH0KRmVhdHVyZVBsb3QoVC5TZXVyYXQsIGZlYXR1cmVzID0gYygiYWR0X0NENCIsIlNlbGwiLCJDZDhiMSIpLGNvbHMgPSBjKCJncmV5IiwgImxpZ2h0IGJsdWUiLCJjeWFuMyIsImN5YW40IiwiZG9kZ2VyYmx1ZTMiLCJibHVlIiwibWVkaXVtc2xhdGVibHVlIiwicHVycGxlIiwib3JjaGlkMyIsInJlZCIsImJyb3duIiwiYmxhY2siKSkKI0ZlYXR1cmVTY2F0dGVyKG9iamVjdCA9IFQuU2V1cmF0LCBmZWF0dXJlMSA9ICJhZHRfQ0Q0IiwgZmVhdHVyZTIgPSAiQ0Q4IiwgY2VsbHMgPSBjb2xuYW1lcyhzdWJzZXQoVC5TZXVyYXQsIGlkZW50cyA9ICIwIikpLCBzbG90ID0gImRhdGEiKQpgYGAKQ2x1c3RlciAxMiBzZWVtcyB0byBjb250YWluIG5haXZlIFNQNCBjZWxscyAoQ0Q0KywgQ2Q4LSBhbmQgQ0Q2MkwgLSkKCiMjIyBDbHVzdGVyIDEzCmBgYHtyIGNsdXN0ZXIxMyxpbmNsdWRlPUZBTFNFfQojbGlzdG1hcmsxMyA8LSAobWFya2Vyc3BsZWVuW3doaWNoIChtYXJrZXJzcGxlZW4kY2x1c3RlciA9PSAiMTMiICYgbWFya2Vyc3BsZWVuJGF2Z19sb2dGQyA+MCksIF0pICNjaG9vc2UgZ2VuZSBvdmVyZXhwcmVzcyBpbiBjbHVzdGVyIDEzIGNlbGxzCiNsaXN0bWFyazEzIDwtIGxpc3RtYXJrMTMkZ2VuZQoKI09uIEltZ2VuIGdlbmUgc2V0IDogSWRlbnRpZnkgYXMgQ0Q4IGFuZC9vciBOS1QKIyBUcnkgdG8gc2VlIGlmIHdlIGNhbiBzdWJkaXZpc2UgdGhpcyBjbHVzdGVyIHRvIGlkZW50aWZ5IGNsZWFyIHBvcHVsYXRpb24KI2NsdXN0ZXIgc3Vic2V0IDEzCklkZW50cyhULlNldXJhdCkgPC0gImludGVncmF0ZWRfc25uX3Jlcy4xLjgiCmNsdXN0ZXIxMyA8LSBzdWJzZXQoVC5TZXVyYXQsICBpZGVudHMgPSBjKCIxMyIpKQpEZWZhdWx0QXNzYXkoY2x1c3RlcjEzKSA8LSAiUk5BIiAjIHRvIGF2b2lkIGVycm9yIHdoZW4gcmUgc3Vic2V0aW5nIGh0dHBzOi8vZ2l0aHViLmNvbS9zYXRpamFsYWIvc2V1cmF0L2lzc3Vlcy8xNTI4CgojY2x1c3RlcjEzIDwtIE5vcm1hbGl6ZURhdGEoY2x1c3RlcjEzLGRpc3BsYXkucHJvZ3Jlc3MgPSBGQUxTRSkKY2x1c3RlcjEzIDwtIEZpbmRWYXJpYWJsZUZlYXR1cmVzKGNsdXN0ZXIxMywgZG8ucGxvdCA9IEYsIHNlbGVjdGlvbi5tZXRob2QgPSAidnN0IiwgbmZlYXR1cmVzID0gMjAwMCwgZGlzcGxheS5wcm9ncmVzcyA9IEZBTFNFKQoKY2x1c3RlcjEzIDwtIFNjYWxlRGF0YSggb2JqZWN0ID0gIGNsdXN0ZXIxMywgCiAgICAgICAgICAgICAgICAgICAgICBhc3NheT0iUk5BIiwKICAgICAgICAgICAgICAgICAgICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICNkby5zY2FsZSA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgZG8uY2VudGVyID0gVFJVRSkKCgpjbHVzdGVyMTMgPC0gUnVuUENBKG9iamVjdCA9IGNsdXN0ZXIxMywgZmVhdHVyZXMgPSBWYXJpYWJsZUZlYXR1cmVzKG9iamVjdCA9IGNsdXN0ZXIxMyksIG5wY3MgPSAxMDAsIHNlZWQudXNlID0gMTIzNCwgdmVyYm9zZSA9IEZBTFNFKQogIApFbGJvd1Bsb3QoY2x1c3RlcjEzLCBuZGltcyA9IDUwLCByZWR1Y3Rpb24gPSAicGNhIikKICAKICAjIFNjb3JlciBsZXMgZ2VuZXMgcG91ciBsZXMgY29tcG9zYW50ZXMKY2x1c3RlcjEzIDwtIFByb2plY3REaW0ob2JqZWN0ID0gY2x1c3RlcjEzLAogICAgICAgICAgICAgICAgICBuZmVhdHVyZXMucHJpbnQgPSAyMCwKICAgICAgICAgICAgICAgICAgZGltcy5wcmludCA9IDE6MjApCiAgCmNsdXN0ZXIxMyA8LSBGaW5kTmVpZ2hib3JzKG9iamVjdCA9IGNsdXN0ZXIxMywKICAgICAgICAgICAgICAgICAgYXNzYXkgPSAiUk5BIiwKICAgICAgICAgICAgICAgICAgZGltcyA9IDE6MjAgLCAKICAgICAgICAgICAgICAgICAgdmVyYm9zZSA9IEZBTFNFKSMsIAogICAgICAgICAgICAgICAgICAjZm9yY2UucmVjYWxjID0gVFJVRSwgCiAgICAgICAgICAgICAgICAgICNyZWR1Y3Rpb24gPSAicGNhIikKICAKY2x1c3RlcjEzIDwtIEZpbmRDbHVzdGVycyhvYmplY3QgPSBjbHVzdGVyMTMsIAogICAgICAgICAgICAgICAgICBhc3NheSA9ICJSTkEiLAogICAgICAgICAgICAgICAgICByZXNvbHV0aW9uID0gMSwKICAgICAgICAgICAgICAgICAgdmVyYm9zZSA9IEZBTFNFLAogICAgICAgICAgICAgICAgICByYW5kb20uc2VlZCA9IDEyMzQpCiAgI1RvIG1ha2UgdGhlIFVNQVAKICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwogIGNsdXN0ZXIxMyA8LSBSdW5VTUFQKG9iamVjdCA9IGNsdXN0ZXIxMywgcmVkdWN0aW9uID0gInBjYSIsIHNlZWQudXNlID0gMTIzNCwgZGltcyA9IDE6MjApCiAgIAogICBEaW1QbG90KGNsdXN0ZXIxMykKICAgCiAgIG1hcmsxMyA8LSBGaW5kQWxsTWFya2VycyhjbHVzdGVyMTMpCiAgIHRvcF9nZW5lc19mZWF0dXJlX3Bsb3QgPC0gbWFyazEzICU+JSBncm91cF9ieShjbHVzdGVyKSAlPiUgdG9wX24oNSwgYXZnX2xvZ0ZDKSAjIHRha2UgNSBmaXJzdCBnZW5lIG9mIGVhY2ggY2x1c3RlcgpgYGAKCgpgYGB7cixmaWcud2lkdGggPSAxNSwgZmlnLmhlaWdodCA9IDh9CnBsb3QxIDwtIERvdFBsb3QoY2x1c3RlcjEzLCBkb3Quc2NhbGUgPSAxMCwgZmVhdHVyZXM9IGMoIkZveHAzIiwiQWVzIiwiQW54YTEiLCJHem1hIiwiQ2NsNSIsIkN4Y3IzIiwiU2VsbCIsIlMxcHIxIiwiQ2NyNyIsIlRyZGMiLCJUY3JnLUM0IiwiVGNyZy1DMiIsIlRjcmctQzEiLCJUcmJjMiIsIlRyYmMxIiwiVHJhYyIsIkNkOGIxIiwiQ2Q0IikpICsgc2NhbGVfY29sb3VyX2dyYWRpZW50Mihsb3cgPSAic3RlZWxibHVlIiwgbWlkID0gIndoaXRlIiwgaGlnaCA9ICJyZWQiKSArIHRoZW1lKAogIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJncmV5NjUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemUgPSAwLjUsIGxpbmV0eXBlID0gInNvbGlkIiksCiAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShzaXplID0gMC41LCBsaW5ldHlwZSA9ICdzb2xpZCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3VyID0gImdyZXk1NSIpKSArIGNvb3JkX2ZsaXAoKQpwbG90MiA8LSBEb3RQbG90KGNsdXN0ZXIxMywgZG90LnNjYWxlID0gMTAsIGZlYXR1cmVzPSB1bmlxdWUodG9wX2dlbmVzX2ZlYXR1cmVfcGxvdCRnZW5lKSkgKyBzY2FsZV9jb2xvdXJfZ3JhZGllbnQyKGxvdyA9ICJzdGVlbGJsdWUiLCBtaWQgPSAid2hpdGUiLCBoaWdoID0gInJlZCIpICsgdGhlbWUoCiAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gImdyZXk2NSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZSA9IDAuNSwgbGluZXR5cGUgPSAic29saWQiKSwKICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKHNpemUgPSAwLjUsIGxpbmV0eXBlID0gJ3NvbGlkJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvdXIgPSAiZ3JleTU1IikpICsgY29vcmRfZmxpcCgpCmdyaWQuYXJyYW5nZShwbG90MSwgcGxvdDIsIG5jb2w9MikKI3RhYmxlKGNsdXN0ZXIxM0BtZXRhLmRhdGEkaW50ZWdyYXRlZF9zbm5fcmVzLjEpCmBgYApUaGlzIGNsdXN0ZXIgaXMgaGV0ZXJvZ2VuZW91cwoKIyMjIENsdXN0ZXIgMTQKYGBge3IsZmlnLndpZHRoID0gMTAsIGZpZy5oZWlnaHQgPSA4fQpGZWF0dXJlUGxvdChULlNldXJhdCwgZmVhdHVyZXMgPSBjKCJhZHRfQ0Q0IiwiQ2Q0IiwiQ2Q4YjEiKSxjb2xzID0gYygiZ3JleSIsICJsaWdodCBibHVlIiwiY3lhbjMiLCJjeWFuNCIsImRvZGdlcmJsdWUzIiwiYmx1ZSIsIm1lZGl1bXNsYXRlYmx1ZSIsInB1cnBsZSIsIm9yY2hpZDMiLCJyZWQiLCJicm93biIsImJsYWNrIikpCmBgYAoKYGBge3IsZmlnLndpZHRoID0gMTUsIGZpZy5oZWlnaHQgPSAxMH0KVmxuUGxvdChULlNldXJhdCwgZmVhdHVyZXMgPSBjKCJQY25hIiwiQ2RrMSIsIk1raTY3IiksbmNvbD0yKSAjdGVpY2htYW5uCmBgYApDbHVzdGVyIDE0IHNlZW1zIHRvIGJlIERwIGJsYXN0CgojIyMgQ2x1c3RlciAxNQpgYGB7ciBjbHVzdGVyMTUsIGZpZy53aWR0aCA9IDEwLCBmaWcuaGVpZ2h0ID0gOH0KRmVhdHVyZVBsb3QoVC5TZXVyYXQsIGZlYXR1cmVzID0gYygiYWR0X0NENCIsIkNkNCIsIkZveHAzIiwiSWwycmEiKSxjb2xzID0gYygiZ3JleSIsICJsaWdodCBibHVlIiwiY3lhbjMiLCJjeWFuNCIsImRvZGdlcmJsdWUzIiwiYmx1ZSIsIm1lZGl1bXNsYXRlYmx1ZSIsInB1cnBsZSIsIm9yY2hpZDMiLCJyZWQiLCJicm93biIsImJsYWNrIikpCmBgYApDbHVzdGVyIDE1IHNlZW1zIHRvIGNvbnRhaW4gVHJlZyAoQ0Q0KywgQ2Q4LSwgQ2QyNSssIEZveHAzKykKCiMjIyBDbHVzdGVyIDE2CgojIyMgQ2x1c3RlciAxNyAKYGBge3IgY2x1c3RlcjE3LGZpZy53aWR0aCA9IDEwLCBmaWcuaGVpZ2h0ID0gOH0KRmVhdHVyZVBsb3QoVC5TZXVyYXQsIGZlYXR1cmVzID0gYygiYWR0X0NENCIsIkNkOGIxIiwiVHJkYyIsIlRjcmctQzEiKSxjb2xzID0gYygiZ3JleSIsICJsaWdodCBibHVlIiwiY3lhbjMiLCJjeWFuNCIsImRvZGdlcmJsdWUzIiwiYmx1ZSIsIm1lZGl1bXNsYXRlYmx1ZSIsInB1cnBsZSIsIm9yY2hpZDMiLCJyZWQiLCJicm93biIsImJsYWNrIikpCmBgYApDbHVzdGVyIDE3IHNlZW0gdG8gY29udGFpbiBUZ2QgRE4gKENENC0sIENkOC0sIFRDUiBEKywgVENSIEcrKQoKIyMjIENsdXN0ZXIgMTgKYGBge3IsZmlnLndpZHRoID0gMTAsIGZpZy5oZWlnaHQgPSA4fQpGZWF0dXJlUGxvdChULlNldXJhdCwgZmVhdHVyZXMgPSBjKCJhZHRfQ0Q0IiwiQ2Q0IiwiQ2Q4YjEiKSxjb2xzID0gYygiZ3JleSIsICJsaWdodCBibHVlIiwiY3lhbjMiLCJjeWFuNCIsImRvZGdlcmJsdWUzIiwiYmx1ZSIsIm1lZGl1bXNsYXRlYmx1ZSIsInB1cnBsZSIsIm9yY2hpZDMiLCJyZWQiLCJicm93biIsImJsYWNrIikpCgpgYGAKCmBgYHtyLGZpZy53aWR0aCA9IDE1LCBmaWcuaGVpZ2h0ID0gMTB9ClZsblBsb3QoVC5TZXVyYXQsIGZlYXR1cmVzID0gYygiUGNuYSIsIkNkazEiLCJNa2k2NyIpLG5jb2w9MikgI3RlaWNobWFubgpgYGAKCkRwIGJsYXN0CgojIyMgQ2x1c3RlciAxOQpgYGB7ciwgZmlnLndpZHRoID0gMTUsIGZpZy5oZWlnaHQgPSAxMn0KRmVhdHVyZVBsb3QoVC5TZXVyYXQsIGZlYXR1cmVzID0gYygiQ2Q4YjEiLCJTZWxsIiwiQ2NsNSIsIkd6bWEiLCJLbHJjMSIsIklmbmciLCJaZWIyIiwiTHk2YzIiKSxuY29sID0gMyxjb2xzID0gYygiZ3JleSIsICJsaWdodCBibHVlIiwiY3lhbjMiLCJjeWFuNCIsImRvZGdlcmJsdWUzIiwiYmx1ZSIsIm1lZGl1bXNsYXRlYmx1ZSIsInB1cnBsZSIsIm9yY2hpZDMiLCJyZWQiLCJicm93biIsImJsYWNrIikpCiMgWmViMiB0ZXJtaW5hbGx5IGRpZmZlcmVudGlhdGVkIENUTApgYGAKCmBgYHtyLGZpZy53aWR0aCA9IDIwLCBmaWcuaGVpZ2h0ID0gNn0KVmxuUGxvdChULlNldXJhdC5zcGxlZW4sIGZlYXR1cmVzID0gYygiU2VsbCIsIkNjcjciLCJJbDdyIikpCmBgYAoKQ2x1c3RlciAxOSBzZWVtc3RvIGNvbnRhaW4gQ0Q4IENUTCAoQ0Q0LSwgQ2Q4KywgQ2NsNSssIFNlbGwtLCBjY3I3LSxjZDEyNy0pICYgTHk2YzIrCgojIyMgQ2x1c3RlciAyMApgYGB7cixmaWcud2lkdGggPSAxMCwgZmlnLmhlaWdodCA9IDh9CkZlYXR1cmVQbG90KFQuU2V1cmF0LCBmZWF0dXJlcyA9IGMoImFkdF9DRDQiLCJDZDQiLCJDZDhiMSIpLGNvbHMgPSBjKCJncmV5IiwgImxpZ2h0IGJsdWUiLCJjeWFuMyIsImN5YW40IiwiZG9kZ2VyYmx1ZTMiLCJibHVlIiwibWVkaXVtc2xhdGVibHVlIiwicHVycGxlIiwib3JjaGlkMyIsInJlZCIsImJyb3duIiwiYmxhY2siKSkKYGBgCgpgYGB7cixmaWcud2lkdGggPSAxNSwgZmlnLmhlaWdodCA9IDEwfQpWbG5QbG90KFQuU2V1cmF0LCBmZWF0dXJlcyA9IGMoIlBjbmEiLCJDZGsxIiwiTWtpNjciKSxuY29sPTIpICN0ZWljaG1hbm4KYGBgCgpTZWVtcyB0byBiZSBEcCBibGFzdAoKIyMjIENsdXN0ZXIgMjEKYGBge3IsZmlnLndpZHRoID0gMTAsIGZpZy5oZWlnaHQgPSA0fQpGZWF0dXJlUGxvdChULlNldXJhdCwgZmVhdHVyZXMgPSBjKCJDZDhiMSIsImFkdF9DRDQiKSkKYGBgCgpgYGB7cixmaWcud2lkdGggPSAyMCwgZmlnLmhlaWdodCA9IDZ9ClZsblBsb3QoVC5TZXVyYXQsIGZlYXR1cmVzID0gYygiQ2Q4YjEiLCJhZHRfQ0Q0IikpCmBgYAoKQ2x1c3RlciAyMSBzZWVtIHRvIGNvbnRhaW4gSVNQIGNlbGxzIChDRDQtLCBDZDgrKQoKIyMjIENsdXN0ZXIgMjIKYGBge3IsZmlnLndpZHRoID0gMTAsIGZpZy5oZWlnaHQgPSA4fQpGZWF0dXJlUGxvdChULlNldXJhdCwgZmVhdHVyZXMgPSBjKCJhZHRfQ0Q0IiwiQ2Q0IiwiQ2Q4YjEiLCJJbDJyYSIpLGNvbHMgPSBjKCJncmV5IiwgImxpZ2h0IGJsdWUiLCJjeWFuMyIsImN5YW40IiwiZG9kZ2VyYmx1ZTMiLCJibHVlIiwibWVkaXVtc2xhdGVibHVlIiwicHVycGxlIiwib3JjaGlkMyIsInJlZCIsImJyb3duIiwiYmxhY2siKSkKYGBgCkNsdXN0ZXIgMjIgc2VlbXMgdG8gY29udGFpbiBETiBUIGNlbGxzIChDRDQtLCBDZDgtLCBDZDI1KykKCiMjIyBDbHVzdGVyIDIzCmBgYHtyLGZpZy53aWR0aCA9IDE1LCBmaWcuaGVpZ2h0ID0gNn0KVmxuUGxvdChULlNldXJhdCwgZmVhdHVyZXMgPSBjKCJDZDhiMSIsImFkdF9DRDQiKSkKVmxuUGxvdChULlNldXJhdCwgZmVhdHVyZXMgPSBjKCJSYWcxIikpICNvbiBEUCBjZWxscyBtb3N0bHkgKGltbWdlbiksIERQIHF1aWNpZW50IG9yIERQIGJsYXN0IChUZWljaG1hbikKYGBgClNlZW1zIHRvIGJlIERwIHNtYWxsIChDZDQrLENkOCssUmFnMSspCgojIyBNWUMgdnMgV1QKIyMjIFJhZGFyIHBsb3QKYGBge3J9CiNjaGVjayBnZW5vdHlwZSBwcm9wb3J0aW9uIGluIGVhY2ggc3BsZWVuIGNsdXN0ZXJzCnBhcihtZnJvdz1jKDEsMikpCmRmIDwtIGFzLmRhdGEuZnJhbWUoYXMuZGF0YS5mcmFtZS5tYXRyaXgodChwcm9wLnRhYmxlKHRhYmxlKFQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGEkSFRPLFQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGEkbWFudWFsY2x1c3RlcnMpLDEpKjEwMCkpKQpkZiRjbHVzdGVyID0gcm93bmFtZXMoZGYpCmRmMjwtYXMuZGF0YS5mcmFtZSh0KGNiaW5kKHJlcCg2MCwxMSkscmVwKDAsMTEpLGRmKVssMTo2XSkpCnJvd25hbWVzKGRmMlsxOjIsXSkgPC0gYygiNjAiLCIwIikKCiNvcmRlciBkYXRhIGZyYW1lCmRmMiA8LSBkZjJbYygiMTAsMTYiLCIxOSIsIjExIiwiMTMiLCIxNyIsIjkiLCIxNSIsIjEyIiwiMCw1IiwiNCIsIjEiKV0KCnJhZGFyY2hhcnQoZGYyLCBjZ2xjb2w9ImdyZXkiLCBjZ2x0eT0xICxjZ2x3ZD0wLjgsIHZsY2V4PTAuOCwgcGNvbD1jKCIjRkY5OUZGIiwiY29yYWwxIiwiY3lhbjMiLCJjaGFydHJldXNlMyIpICwgcGx3ZD0zLCBwbHR5PTEgLGNheGlzbGFiZWxzPXBhc3RlKHNlcShmcm9tID0gMCx0byA9IDYwLGJ5ID0gMTUpLCIlIiksIGF4aXNsYWJjb2wgPSAiZ3JleTQwIiwgYXhpc3R5cGUgPSAwKQoKI2NoZWNrIGdlbm90eXBlIHByb3BvcnRpb24gaW4gZWFjaCB0aHltaWMgY2x1c3RlcgpkZiA8LSAgYXMuZGF0YS5mcmFtZShhcy5kYXRhLmZyYW1lLm1hdHJpeCh0KHByb3AudGFibGUodGFibGUoVC5TZXVyYXQudGh5bXVzQG1ldGEuZGF0YSRIVE8sVC5TZXVyYXQudGh5bXVzQG1ldGEuZGF0YSRtYW51YWxjbHVzdGVycyksMSkqMTAwKSkpCmRmJGNsdXN0ZXIgPSByb3duYW1lcyhkZikKZGYyPC1hcy5kYXRhLmZyYW1lKHQoY2JpbmQocmVwKDY1LDgpLHJlcCgwLDgpLGRmKVssMTo2XSkpCnJvd25hbWVzKGRmMlsxOjIsXSkgPC0gYygiNjUiLCIwIikKCiNvcmRlcgpkZjIgPC0gZGYyW2MoIjIyIiwiMTciLCIxMCwxNiIsIjYiLCI3IiwiOCwyLDMsMjMiLCIyMCwxOCwxNCIsIjIxIildCgoKcmFkYXJjaGFydChkZjIsIGNnbGNvbD0iZ3JleSIsIGNnbHR5PTEsY2F4aXNsYWJlbHM9cGFzdGUoc2VxKDAsNzAsMTcuNSksIiUiKSwgYXhpc3R5cGUgPSAwLGF4aXNsYWJjb2w9ImdyZXk0MCIsIGNnbHdkPTAuOCwgdmxjZXg9MC44LCBwY29sPWMoIiNGRjk5RkYiLCJjb3JhbDEiLCJjeWFuMyIsImNoYXJ0cmV1c2UzIikgLCBwbHdkPTMsIHBsdHk9MSApCgojcGFyKG1mcm93ID0gYygxLDEpKQpgYGAKIyMjIFByb3BvcnRpb24gYmFyIHBsb3QKYGBge3J9CiN0aHltaWMgcHJvcG9ydGlvbnMKZGF0YXRoeW0gPC0gZGF0YS5mcmFtZShwcm9wLnRhYmxlKHQocHJvcC50YWJsZSh0YWJsZShULlNldXJhdC50aHltdXNAbWV0YS5kYXRhJEhUTyxULlNldXJhdC50aHltdXNAbWV0YS5kYXRhJG1hbnVhbGNsdXN0ZXJzKSwxKSksMSkqMTAwKQojb3JkZXIgY2x1c3RlciBsZXZlbApkYXRhdGh5bSRWYXIxIDwtIGZhY3RvcihkYXRhdGh5bSRWYXIxLCBsZXZlbHMgPSBjKCIyMiIsIjIxIiwiMjAsMTgsMTQiLCI4LDIsMywyMyIsIjciLCI2IiwiMTAsMTYiLCIxNyIpKQoKY2VsbG51bWJlciA8LSBkYXRhLmZyYW1lKGNvbFN1bXModGFibGUoVC5TZXVyYXQudGh5bXVzQG1ldGEuZGF0YSRIVE8sVC5TZXVyYXQudGh5bXVzQG1ldGEuZGF0YSRtYW51YWxjbHVzdGVycykpICkKY2VsbG51bWJlciRjbHVzdGVyIDwtIHJvd25hbWVzKGNlbGxudW1iZXIpCnJvd19vcmRlciA8LSBjKCIyMiIsIjIxIiwiMjAsMTgsMTQiLCI4LDIsMywyMyIsIjYiLCI3IiwiMTciLCIxMCwxNiIpCmNlbGxudW1iZXIgPC0gY2VsbG51bWJlcltyb3dfb3JkZXIsXQoKQ2x1c3RlciA8LSBkYXRhdGh5bSRWYXIxCkhUTyA8LSBkYXRhdGh5bSRWYXIyClBlcmNlbnRhZ2UgPC0gZGF0YXRoeW0kRnJlcQp0ZXh0IDwtIGNlbGxudW1iZXIkY29sU3Vtcy50YWJsZS5ULlNldXJhdC50aHltdXMubWV0YS5kYXRhLkhUTy4uVC5TZXVyYXQudGh5bXVzLm1ldGEuZGF0YS5tYW51YWxjbHVzdGVycy4uCgpjb2xzIDwtIGMoIk15Yy0gUFRFTi0gdGh5bXVzIiA9ICIjRkY5OUZGIiwgIk1ZQy0gdGh5bXVzIiA9ICJjb3JhbDEiLCAiUFRFTi0gdGh5bXVzIiA9ICJjeWFuMyIsICJXVCB0aHltdXMiID0gImNoYXJ0cmV1c2UzIikKCmdncGxvdChkYXRhdGh5bSwgYWVzKGZpbGw9SFRPLCB5PVBlcmNlbnRhZ2UsIHg9Q2x1c3RlcikpICsgCiAgICBnZW9tX2Jhcihwb3NpdGlvbj0ic3RhY2siLCBzdGF0PSJpZGVudGl0eSIsIHdpZHRoPTAuNykrCiAgIHhsYWIoIlRoeW1pYyBDbHVzdGVycyIpK3lsYWIoIlBlcmNlbnRhZ2UiKSsgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJib3R0b20iKSsgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID1jb2xzLCBsYWJlbHM9YygiTXljIFB0ZW4iLCJNeWMiLCJQdGVuIiwiV1QiKSkrdGhlbWVfbGlnaHQoKStnZW9tX2hsaW5lKHlpbnRlcmNlcHQ9YygyNSw1MCw3NSksIGxpbmV0eXBlPSJkYXNoZWQiLCBjb2xvciA9ICJncmV5NjAiKSsgYW5ub3RhdGUoInRleHQiLCB4ID0gYygxLDIsMyw0LDUsNiw3LDgpLCB5PTEwMywgbGFiZWwgPSBjKHBhc3RlMCh0ZXh0KSkpCgojc3BsZW5pYyBwcm9wb3J0aW9ucwpJZGVudHMoVC5TZXVyYXQuc3BsZWVuKSA8LSAibWFudWFsY2x1c3RlcnMiClQuU2V1cmF0LnNwbGVlbmJhciA8LSBzdWJzZXQoVC5TZXVyYXQuc3BsZWVuLCAgaWRlbnRzID0gYygiMCw1IiwiOSIsIjEiLCIxMSIsIjE5IikpICN0byBvbmx5IGtlZXAgY2x1c3RlciBuZWVkZWQgZm9yIHRoZSBwbG90CmRhdGEzIDwtIGRhdGEuZnJhbWUocHJvcC50YWJsZSh0KHByb3AudGFibGUodGFibGUoVC5TZXVyYXQuc3BsZWVuYmFyQG1ldGEuZGF0YSRIVE8sVC5TZXVyYXQuc3BsZWVuYmFyQG1ldGEuZGF0YSRtYW51YWxjbHVzdGVycyksMSkpLDEpKjEwMCkKCiNvcmRlciBjbHVzdGVyIGxldmVsCmRhdGEzJFZhcjEgPC0gZmFjdG9yKGRhdGEzJFZhcjEsIGxldmVscyA9IGMoIjAsNSIsIjkiLCIxIiwiMTEiLCIxOSIpKQoKY2VsbG51bWJlciA8LSBkYXRhLmZyYW1lKGNvbFN1bXModGFibGUoVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YSRIVE8sVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YSRtYW51YWxjbHVzdGVycykpICkKY2VsbG51bWJlciRjbHVzdGVyIDwtIHJvd25hbWVzKGNlbGxudW1iZXIpCnJvd19vcmRlciA8LWMoIjAsNSIsIjkiLCIxIiwiMTEiLCIxOSIpCmNlbGxudW1iZXIgPC0gY2VsbG51bWJlcltyb3dfb3JkZXIsXQoKQ2x1c3RlciA8LSBkYXRhMyRWYXIxCkhUTyA8LSBkYXRhMyRWYXIyClBlcmNlbnRhZ2UgPC0gZGF0YTMkRnJlcQp0ZXh0IDwtIGNlbGxudW1iZXIkY29sU3Vtcy50YWJsZS5ULlNldXJhdC5zcGxlZW4ubWV0YS5kYXRhLkhUTy4uVC5TZXVyYXQuc3BsZWVuLm1ldGEuZGF0YS5tYW51YWxjbHVzdGVycy4uCiMgU3RhY2tlZCBiYXIgcGxvdApjb2xzIDwtIGMoIk15Yy0gUFRFTi0gc3BsZWVuIiA9ICIjRkY5OUZGIiwgIk1ZQy0gc3BsZWVuIiA9ICJjb3JhbDEiLCAiUFRFTi0gc3BsZWVuIiA9ICJjeWFuMyIsICJXVCBzcGxlZW4iID0gImNoYXJ0cmV1c2UzIikKCmdncGxvdChkYXRhMywgYWVzKGZpbGw9SFRPLCB5PVBlcmNlbnRhZ2UsIHg9Q2x1c3RlcikpICsgCiAgICBnZW9tX2Jhcihwb3NpdGlvbj0ic3RhY2siLCBzdGF0PSJpZGVudGl0eSIsIHdpZHRoPTAuNykrCiAgIHhsYWIoIlNwbGVuaWMgQ2x1c3RlcnMiKSt5bGFiKCJQZXJjZW50YWdlIikrIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0iYm90dG9tIikrc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID1jb2xzLCBsYWJlbHM9YygiTXljIFB0ZW4iLCJNeWMiLCJQdGVuIiwiV1QiKSkgK3RoZW1lX2xpZ2h0KCkrZ2VvbV9obGluZSh5aW50ZXJjZXB0PWMoMjUsNTAsNzUpLCBsaW5ldHlwZT0iZGFzaGVkIiwgY29sb3IgPSAiZ3JleTYwIikrIGFubm90YXRlKCJ0ZXh0IiwgeCA9IGMoMSwyLDMsNCw1KSwgeT0xMDMsIGxhYmVsID0gYyh0ZXh0KSkKYGBgCgojIyMgRGlmZmVyZW50aWFsIEdlbmUgRXhwcmVzc2lvbgojIyMjIENEOApgYGB7cn0KSWRlbnRzKFQuU2V1cmF0KSA8LSAiaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCIKI0RHRSBiZXR3ZWVuIG91ciB0d28gQ0Q4IG5haXZlIGNsdXN0ZXJzCmRnZWNkOF9kYXRhIDwtIEZpbmRNYXJrZXJzKFQuU2V1cmF0LCBpZGVudC4xID0gIjEiLCBpZGVudC4yID0gIjQiLGxvZ2ZjLnRocmVzaG9sZD0wKQoKIyBiYXIgcGxvdAojYWRkIGFicyB2YWx1ZSB0byB0YWJsZQpkZ2VjZDhfZGF0YSRhYnMgPC0gYWJzKGRnZWNkOF9kYXRhJGF2Z19sb2dGQykgCgpkZ2VjZDhfZGF0YSRnZW5lbmFtZSA8LSByb3duYW1lcyhkZ2VjZDhfZGF0YSkKIyBTZWxlY3QgbWFya2VycyBmb3IgcGxvdHRpbmcgb24gYSBIZWF0bWFwIAptYXJrZXJzLnVzZT1zdWJzZXQoZGdlY2Q4X2RhdGEsIHBfdmFsX2FkajwxZS01MCAmIGFicz4wLjIwKQpkZmNkOG1hcmtlcnMgPC1tYXJrZXJzLnVzZVtvcmRlcihtYXJrZXJzLnVzZSRhdmdfbG9nRkMpLF0KCmRmY2Q4bWFya2VycyRnZW5lbmFtZSA8LSBmYWN0b3IoZGZjZDhtYXJrZXJzJGdlbmVuYW1lLCBsZXZlbHMgPSBkZmNkOG1hcmtlcnMkZ2VuZW5hbWVbb3JkZXIoZGZjZDhtYXJrZXJzJGF2Z19sb2dGQyldKQpkZmNkOG1hcmtlcnMkbG9ncHZhbCA8LSBsb2cxMChkZmNkOG1hcmtlcnMkcF92YWxfYWRqKQpgYGAKCmBgYHtyLGZpZy53aWR0aCA9IDEwLCBmaWcuaGVpZ2h0ID0gOH0KZ2dwbG90KGRmY2Q4bWFya2VycywgYWVzKHggPSBkZmNkOG1hcmtlcnMkZ2VuZW5hbWUsIHkgPSBkZmNkOG1hcmtlcnMkYXZnX2xvZ0ZDLCBmaWxsID0gbG9ncHZhbCkpICsgICAjIEZpbGwgY29sdW1uCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCB3aWR0aCA9IC42KSArICAgIyBkcmF3IHRoZSBiYXJzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHlsaW0oLTEuMiwxLjIpKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJzKHRpdGxlPSJER0UgLSBDbHVzdGVyIDEgdnMgNCAoQ2Q4IG5haXZlKSIseSA9IkxvZyBmb2xkIGNoYW5nZSIsIHggPSAiR2VuZXMgZGlmZmVyZW50aWFsbHkgZXhwcmVzc2VkIikgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVtZV90dWZ0ZSgpICsgICMgVHVmdGUgdGhlbWUgZnJvbSBnZ2ZvcnRpZnkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IC41KSxheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCB2anVzdCA9IDAuNSwgaGp1c3Q9MSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FsZV9maWxsX2dyYWRpZW50Mihsb3c9J3JlZCcsIG1pZD0nb3JhbmdlJywgaGlnaD0nYmx1ZScsbWlkcG9pbnQgPSAtMTIwLCBicmVha3M9YygtNTIsLTEyMCwtMjAwKSxsYWJlbHM9YygiLTUwIiwiLTEyMCIsIi0yMDAiKSkrY29vcmRfZmxpcCgpICMgRmxpcCBheGVzCmBgYAoKIyMjIyBDRDQKCmRlZmluZSBwcm9wb3J0aW9uIG9mIGdlbm90eXBlIGluIENENCBuYWl2ZSBjbHVzdGVycyA6CmBgYHtyfQpULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhJG1hbnVhbEhUTyA9ICJub3RoaW5nIgpJZGVudHMoVC5TZXVyYXQuc3BsZWVuKSA8LSAiTVVMVElfSUQiClQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGFbV2hpY2hDZWxscyhULlNldXJhdC5zcGxlZW4sIHNsb3QgPSAiTVVMVElfSUQiLCBpZGVudHMgPSBjKCJTcGxlZW4tY3RybCIsIlNwbGVlbi1QIikpLF0kbWFudWFsSFRPID0gIlNwbGVlbi1jdHJsJlAiClQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGFbV2hpY2hDZWxscyhULlNldXJhdC5zcGxlZW4sIHNsb3QgPSAiTVVMVElfSUQiLCBpZGVudHMgPSBjKCJTcGxlZW4tTSIsIlNwbGVlbi1NUCIpKSxdJG1hbnVhbEhUTyA9ICJTcGxlZW4tTSZNUCIKCnRhYiA8LSAocHJvcC50YWJsZSh0KHByb3AudGFibGUodGFibGUoVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YSRpbnRlZ3JhdGVkX3Nubl9yZXMuMS44LFQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGEkbWFudWFsSFRPKSwxKSksMikqMTAwKQpgYGAKSW4gb3VyIENENCBuYWl2ZSBjbHVzdGVycyAoMCw1IGFuZCAxMikgdGhlIG9uZSB3aXRoIG1vc3QgY2VsbHMgZnJvbSBNJk1QIGlzIDAgYW5kIHRoZSBvbmUgd2l0aCBtb3N0IGNlbGxzIGZyb20gY3RybCZQIGlzIDEyCgpgYGB7cn0KSWRlbnRzKFQuU2V1cmF0KSA8LSAiaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCIKI0RHRSBiZXR3ZWVuIDAgYW5kIDEyCmRnZWNkNF9kYXRhIDwtIEZpbmRNYXJrZXJzKFQuU2V1cmF0LCBpZGVudC4xID0gIjAiLCBpZGVudC4yID0gIjEyIixsb2dmYy50aHJlc2hvbGQ9MCkKIyBiYXIgcGxvdAojYWRkIGFicyB2YWx1ZSB0byB0YWJsZQpkZ2VjZDRfZGF0YSRhYnMgPC0gYWJzKGRnZWNkNF9kYXRhJGF2Z19sb2dGQykgCgpkZ2VjZDRfZGF0YSRnZW5lbmFtZSA8LSByb3duYW1lcyhkZ2VjZDRfZGF0YSkKIyBTZWxlY3QgbWFya2VycyBmb3IgcGxvdHRpbmcgb24gYSBIZWF0bWFwIAptYXJrZXJzLnVzZT1zdWJzZXQoZGdlY2Q0X2RhdGEscF92YWxfYWRqPDFlLTEwICYgYWJzPjAuMikKZGZjZDRtYXJrZXJzIDwtbWFya2Vycy51c2Vbb3JkZXIobWFya2Vycy51c2UkYXZnX2xvZ0ZDKSxdCgpkZmNkNG1hcmtlcnMkZ2VuZW5hbWUgPC0gZmFjdG9yKGRmY2Q0bWFya2VycyRnZW5lbmFtZSwgbGV2ZWxzID0gZGZjZDRtYXJrZXJzJGdlbmVuYW1lW29yZGVyKGRmY2Q0bWFya2VycyRhdmdfbG9nRkMpXSkKZGZjZDRtYXJrZXJzJGxvZ3B2YWwgPC0gbG9nMTAoZGZjZDRtYXJrZXJzJHBfdmFsX2FkaikKYGBgCgpgYGB7cixmaWcud2lkdGggPSAxMCwgZmlnLmhlaWdodCA9IDh9CmdncGxvdChkZmNkNG1hcmtlcnMsIGFlcyh4ID0gZGZjZDRtYXJrZXJzJGdlbmVuYW1lLCB5ID0gZGZjZDRtYXJrZXJzJGF2Z19sb2dGQywgZmlsbCA9IGxvZ3B2YWwpKSArICAgIyBGaWxsIGNvbHVtbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5Iiwgd2lkdGggPSAuNikgKyAgICMgZHJhdyB0aGUgYmFycwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5bGltKC0xLjIsMS4yKSsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFicyh0aXRsZT0iREdFIC0gQ2x1c3RlciAwIHZzIDEyIChDZDQgbmFpdmUpIix5ID0iTG9nIGZvbGQgY2hhbmdlIiwgeCA9ICJHZW5lcyBkaWZmZXJlbnRpYWxseSBleHByZXNzZWQiKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW1lX3R1ZnRlKCkgKyAgIyBUdWZ0ZSB0aGVtZSBmcm9tIGdnZm9ydGlmeQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gLjUpLGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIHZqdXN0ID0gMC41LCBoanVzdD0xKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF4aXMudGlja3MgPSBlbGVtZW50X2JsYW5rKCkpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjYWxlX2ZpbGxfZ3JhZGllbnQyKGxvdz0ncmVkJywgbWlkPSdvcmFuZ2UnLCBoaWdoPSdibHVlJyxtaWRwb2ludCA9IC00MCwgYnJlYWtzPWMoLTEyLC00MCwtNTcpLGxhYmVscz1jKCItMTAiLCItNDAiLCItNjAiKSkrIGNvb3JkX2ZsaXAoKSAjIEZsaXAgYXhlcwpgYGAKCgojIyMgRnVuY3Rpb25hbCBwcm9maWwgYW5hbHlzaXMgKEdlbmUgT250b2xvZ3kpCmBgYHtyfQpJZGVudHMoVC5TZXVyYXQpIDwtICJpbnRlZ3JhdGVkX3Nubl9yZXMuMS44IgoKIyBnZXQgYWxsIGdlbmUgbmFtZSBleHByZXNzIGluIG91ciBjZWxscyBhcyBiYWNrZ3JvdW5kCmJhY2tncm91bmQgPC0gVC5TZXVyYXRAYXNzYXlzJFJOQUBtZXRhLmZlYXR1cmVzCmJhY2tncm91bmRyb3cgPC0gcm93bmFtZXMoYmFja2dyb3VuZCkKYGBgCgojIyMjIE5haXZlIENEOCBUIGNlbGxzCmBgYHtyfQojREdFIGJldHdlZW4gb3VyIHR3byBDRDggbmFpdmUgY2x1c3RlcnMKI2RnZWNkOF9kYXRhIDwtIEZpbmRNYXJrZXJzKFQuU2V1cmF0LCBpZGVudC4xID0gIjEiLCBpZGVudC4yID0gIjQiLGxvZ2ZjLnRocmVzaG9sZD0wKQojdXByZWdfY2Q4IDwtIHN1YnNldChkZ2VjZDhfZGF0YSwgYXZnX2xvZ0ZDPjApCiNkb3ducmVnX2NkOCA8LSBzdWJzZXQoZGdlY2Q4X2RhdGEsIGF2Z19sb2dGQzwwLjIgJiBwX3ZhbF9hZGo8MWUtNTApCiNnZW5lY29tcHJvdyA8LSByb3duYW1lcyhkb3ducmVnX2NkOCkKCgojIyMjIFRPIFNVUFBSRVNTIEZPUiBGSU5BTAojd3JpdGUudGFibGUoZ2VuZWNvbXByb3csZmlsZT0iL2hvbWUvbm96YWlzbS9Xb3Jrc3BhY2UvMDFfVGhlc2UvMDFfUHJvamVjdC9NeWNfUHRlbl9QYXBlci9jbHVzdGVyMXY0LnR4dCIsc2VwPSJcdCIscXVvdGU9RikKZ2VuZWNvbXByb3cgPC0gcmVhZC50YWJsZSgiL2hvbWUvbm96YWlzbS9Xb3Jrc3BhY2UvMDFfVGhlc2UvMDFfUHJvamVjdC9NeWNfUHRlbl9QYXBlci9jbHVzdGVyMXY0LnR4dCIsIHNlcCA9ICJcdCIpCmdlbmVjb21wcm93JHggPSBhcy5jaGFyYWN0ZXIoZ2VuZWNvbXByb3ckeCkKZ2VuZWNvbXByb3cgPC0gZ2VuZWNvbXByb3dbLDFdCgpDUGVucmljaCA8LSBlbnJpY2hHTyhnZW5lPSBnZW5lY29tcHJvdywgT3JnRGIgPSAnb3JnLk1tLmVnLmRiJywgb250PSJCUCIsa2V5VHlwZSA9ICJTWU1CT0wiLHVuaXZlcnNlID0gYmFja2dyb3VuZHJvdykgIyBvcmcuTW0uZWcuZGIgZ2Vub21lIG1vdXNlCiNoZWFkIChDUGVucmljaCkKYGBgCgpgYGB7cixmaWcud2lkdGggPSAxMiwgZmlnLmhlaWdodCA9IDZ9CmRvdHBsb3QoQ1BlbnJpY2gsIHNob3dDYXRlZ29yeT0xNSxjb2xvciA9ICJwLmFkanVzdCIseD0iY291bnQiKSAjKyBjb29yZF9mbGlwKCkrdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgaGp1c3QgPSAxKSkKYGBgCgpgYGB7cixmaWcud2lkdGggPSAxMiwgZmlnLmhlaWdodCA9IDh9CmVtYXBwbG90KENQZW5yaWNoLCBzaG93Q2F0ZWdvcnkgPSA1MCkKYGBgCgoKIyMjIyBOYWl2ZSBDRDQgVCBjZWxscwpgYGB7cn0KI0RHRSBiZXR3ZWVuIG91ciB0d28gbW9zdCBjb250cm9sIGFuZCBNeWQgZGVsIENENCBuYWl2ZSBjbHVzdGVycwojZGdlY2Q0X2RhdGEgPC0gRmluZE1hcmtlcnMoVC5TZXVyYXQsIGlkZW50LjEgPSAiMCIsIGlkZW50LjIgPSAiMTIiLGxvZ2ZjLnRocmVzaG9sZD0wKQojZG93bnJlZ19jZDQgPC0gc3Vic2V0KGRnZWNkNF9kYXRhLCBhdmdfbG9nRkM8MCYgcF92YWxfYWRqPDFlLTIwKQojZ2VuZWNvbXByb3cgPC0gcm93bmFtZXMoZG93bnJlZ19jZDQpCgoKIyMjIyBUTyBTVVBQUkVTUyBGT1IgRklOQUwKI3dyaXRlLnRhYmxlKGdlbmVjb21wcm93LGZpbGU9Ii9ob21lL25vemFpc20vV29ya3NwYWNlLzAxX1RoZXNlLzAxX1Byb2plY3QvTXljX1B0ZW5fUGFwZXIvY2x1c3RlcjB2czEyLnR4dCIsc2VwPSJcdCIscXVvdGU9RikKZ2VuZWNvbXByb3cgPC0gcmVhZC50YWJsZSgiL2hvbWUvbm96YWlzbS9Xb3Jrc3BhY2UvMDFfVGhlc2UvMDFfUHJvamVjdC9NeWNfUHRlbl9QYXBlci9jbHVzdGVyMHZzMTIudHh0Iiwgc2VwID0gIlx0IikKZ2VuZWNvbXByb3ckeCA9IGFzLmNoYXJhY3RlcihnZW5lY29tcHJvdyR4KQpnZW5lY29tcHJvdyA8LSBnZW5lY29tcHJvd1ssMV0KIyMjIwoKCkNQZW5yaWNoIDwtIGVucmljaEdPKGdlbmU9IGdlbmVjb21wcm93LCBPcmdEYiA9ICdvcmcuTW0uZWcuZGInLCBvbnQ9IkJQIixrZXlUeXBlID0gIlNZTUJPTCIsdW5pdmVyc2UgPSBiYWNrZ3JvdW5kcm93KSAjIG9yZy5NbS5lZy5kYiBnZW5vbWUgbW91c2UKCmBgYAoKYGBge3IsZmlnLndpZHRoID0gOSwgZmlnLmhlaWdodCA9IDYgfQpkb3RwbG90KENQZW5yaWNoLCBzaG93Q2F0ZWdvcnk9MTUsY29sb3IgPSAicC5hZGp1c3QiLHg9ImNvdW50IikrIHNjYWxlX3lfZGlzY3JldGUobGFiZWxzPWZ1bmN0aW9uKHgpc3RyX3dyYXAoeCwgd2lkdGg9NDApKQpgYGAKCgojIyMgZVlGUCBuZWdhdGl2ZSBpbnZlc3RpZ2F0aW9uCkRlY2lwaGVyaW5nIHdoYXQgYXJlIG91ciBlWUZQIG5lZ2F0aXZlIGNlbGxzIG9uIGVmZmVjdG9yIGFuZCBtZW1vcnkgQ0Q4IFQgY2VsbHMKCkhlYXRtYXAgOiAKYGBge3J9CiMgT24gY2x1c3RlciAxMSAtIGNkOCBtZW1vcnkKQzExQ3RybCA8LXJvd25hbWVzKFQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGFbVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YSRNVUxUSV9JRCA9PSAiU3BsZWVuLWN0cmwiICYgVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YSRpbnRlZ3JhdGVkX3Nubl9yZXMuMS44ID09ICIxMSIsXSkKbUMxMUN0cmwgPC0gbWVhbihULlNldXJhdC5zcGxlZW5AYXNzYXlzJFJOQUBkYXRhWyJlWUZQIixDMTFDdHJsXSkKQzExUHQgPC0gcm93bmFtZXMoVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YVtULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhJE1VTFRJX0lEID09ICJTcGxlZW4tUCIgJiBULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhJGludGVncmF0ZWRfc25uX3Jlcy4xLjggPT0gIjExIixdKQptQzExUHQgPC0gbWVhbihULlNldXJhdC5zcGxlZW5AYXNzYXlzJFJOQUBkYXRhWyJlWUZQIixDMTFQdF0pCkMxMU1QIDwtIHJvd25hbWVzKFQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGFbVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YSRNVUxUSV9JRCA9PSAiU3BsZWVuLU1QIiAmIFQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGEkaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCA9PSAiMTEiLF0pCm1DMTFNUCA8LSBtZWFuKFQuU2V1cmF0LnNwbGVlbkBhc3NheXMkUk5BQGRhdGFbImVZRlAiLEMxMU1QXSkKQzExTSA8LSByb3duYW1lcyhULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhW1QuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGEkTVVMVElfSUQgPT0gIlNwbGVlbi1NIiAmIFQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGEkaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCA9PSAiMTEiLF0pCm1DMTFNIDwtIG1lYW4oVC5TZXVyYXQuc3BsZWVuQGFzc2F5cyRSTkFAZGF0YVsiZVlGUCIsQzExTV0pCiNvbiBjbHVzdGVyIDE5IC0gY2Q4IGVmZiB0ZXJtCkMxOUN0cmwgPC1yb3duYW1lcyhULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhW1QuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGEkTVVMVElfSUQgPT0gIlNwbGVlbi1jdHJsIiAmIFQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGEkaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCA9PSAiMTkiLF0pCm1DMTlDdHJsIDwtIG1lYW4oVC5TZXVyYXQuc3BsZWVuQGFzc2F5cyRSTkFAZGF0YVsiZVlGUCIsQzE5Q3RybF0pCkMxOVB0IDwtIHJvd25hbWVzKFQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGFbVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YSRNVUxUSV9JRCA9PSAiU3BsZWVuLVAiICYgVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YSRpbnRlZ3JhdGVkX3Nubl9yZXMuMS44ID09ICIxOSIsXSkKbUMxOVB0IDwtIG1lYW4oVC5TZXVyYXQuc3BsZWVuQGFzc2F5cyRSTkFAZGF0YVsiZVlGUCIsQzE5UHRdKQpDMTlNUCA8LSByb3duYW1lcyhULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhW1QuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGEkTVVMVElfSUQgPT0gIlNwbGVlbi1NUCIgJiBULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhJGludGVncmF0ZWRfc25uX3Jlcy4xLjggPT0gIjE5IixdKQptQzE5TVAgPC0gbWVhbihULlNldXJhdC5zcGxlZW5AYXNzYXlzJFJOQUBkYXRhWyJlWUZQIixDMTlNUF0pCkMxOU0gPC0gcm93bmFtZXMoVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YVtULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhJE1VTFRJX0lEID09ICJTcGxlZW4tTSIgJiBULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhJGludGVncmF0ZWRfc25uX3Jlcy4xLjggPT0gIjE5IixdKQptQzE5TSA8LSBtZWFuKFQuU2V1cmF0LnNwbGVlbkBhc3NheXMkUk5BQGRhdGFbImVZRlAiLEMxOU1dKQojb24gY2x1c3RlciAxCkMxQ3RybCA8LXJvd25hbWVzKFQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGFbVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YSRNVUxUSV9JRCA9PSAiU3BsZWVuLWN0cmwiICYgVC5TZXVyYXQuc3BsZWVuQG1ldGEuZGF0YSRpbnRlZ3JhdGVkX3Nubl9yZXMuMS44ID09ICIxIixdKQptQzFDdHJsIDwtIG1lYW4oVC5TZXVyYXQuc3BsZWVuQGFzc2F5cyRSTkFAZGF0YVsiZVlGUCIsQzFDdHJsXSkKQzFQdCA8LSByb3duYW1lcyhULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhW1QuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGEkTVVMVElfSUQgPT0gIlNwbGVlbi1QIiAmIFQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGEkaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCA9PSAiMSIsXSkKbUMxUHQgPC0gbWVhbihULlNldXJhdC5zcGxlZW5AYXNzYXlzJFJOQUBkYXRhWyJlWUZQIixDMVB0XSkKQzFNUCA8LSByb3duYW1lcyhULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhW1QuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGEkTVVMVElfSUQgPT0gIlNwbGVlbi1NUCIgJiBULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhJGludGVncmF0ZWRfc25uX3Jlcy4xLjggPT0gIjEiLF0pCm1DMU1QIDwtIG1lYW4oVC5TZXVyYXQuc3BsZWVuQGFzc2F5cyRSTkFAZGF0YVsiZVlGUCIsQzFNUF0pCkMxTSA8LSByb3duYW1lcyhULlNldXJhdC5zcGxlZW5AbWV0YS5kYXRhW1QuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGEkTVVMVElfSUQgPT0gIlNwbGVlbi1NIiAmIFQuU2V1cmF0LnNwbGVlbkBtZXRhLmRhdGEkaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCA9PSAiMSIsXSkKbUMxTSA8LSBtZWFuKFQuU2V1cmF0LnNwbGVlbkBhc3NheXMkUk5BQGRhdGFbImVZRlAiLEMxTV0pCgoKbDEgPC0gYygiMSIsIjEiLCIxIiwiMSIsIjExIiwiMTEiLCIxMSIsIjExIiwiMTkiLCIxOSIsIjE5IiwiMTkiKQpsMiA8LSBjKCJDdHJsIiwiUHRlbiIsIk15YyIsIk15Y1B0ZW4iLCJDdHJsIiwiUHRlbiIsIk15YyIsIk15Y1B0ZW4iLCJDdHJsIiwiUHRlbiIsIk15YyIsIk15Y1B0ZW4iKQpsMyA8LSBjKG1DMUN0cmwsbUMxUHQsbUMxTSxtQzFNUCxtQzExQ3RybCxtQzExUHQsbUMxMU0sbUMxMU1QLG1DMTlDdHJsLG1DMTlQdCxtQzE5TSxtQzE5TVApCgp0YWJsZWF1WUZQIDwtIGRhdGEuZnJhbWUoQ2x1c3RlciA9IGwxLCBHZW5vdHlwZXMgPWwyKSAKdGFibGVhdVlGUCA8LSBjYmluZCh0YWJsZWF1WUZQLFZhbHVlcyA9IGwzKQoKCnRhYmxlYXVZRlAkQ2x1c3RlciA8LSBmYWN0b3IodGFibGVhdVlGUCRDbHVzdGVyLGxldmVscyA9IGMoIjEiLCIxMSIsIjE5IikpCnRhYmxlYXVZRlAkR2Vub3R5cGVzIDwtIGZhY3Rvcih0YWJsZWF1WUZQJEdlbm90eXBlcyxsZXZlbHMgPSBjKCJNeWNQdGVuIiwiTXljIiwiUHRlbiIsIkN0cmwiKSkKYGBgCgpgYGB7cixmaWcud2lkdGggPSA3LCBmaWcuaGVpZ2h0ID0gNX0KZ2dwbG90KHRhYmxlYXVZRlAsIGFlcyh4ID0gQ2x1c3RlciwgR2Vub3R5cGVzKSkgKwogICAgICAgIGdlb21fdGlsZShhZXMoZmlsbCA9IFZhbHVlcykpICsKICAgICAgICBzY2FsZV9maWxsX2dyYWRpZW50MiggbWlkPSd5ZWxsb3cnLCBoaWdoPSdyZWQnLGxpbWl0cz1jKDAsbWF4KHRhYmxlYXVZRlAkVmFsdWVzKSkpKyB0aGVtZV9jbGFzc2ljKGJhc2Vfc2l6ZT0yMCkKYGBgCgplWUZQIG5lYWd0aXZlIGFyZSBjb21pbmcgZnJvbSBNeWMgYW5kIE15YyBQdGVuIGRlbCBtaWNlCgpgYGB7cn0KI0RPVCBwbG90IGV5RlAgYW5kIFRHRCBvbiBDRDggZWZmZWN0b3IgYW5kIG1lbW9yeQpJZGVudHMoVC5TZXVyYXQuc3BsZWVuKSA8LSAiaW50ZWdyYXRlZF9zbm5fcmVzLjEuOCIKQ0Q4c3ViIDwtIHN1YnNldChULlNldXJhdC5zcGxlZW4sIGlkZW50cyA9IGMoIjExIiwiMTkiLCIxMyIpKQpJZGVudHMoQ0Q4c3ViKSA8LSAiTVVMVElfSUQiCkNEOHN1YkBhY3RpdmUuaWRlbnQgPC0gZmFjdG9yKENEOHN1YkBhY3RpdmUuaWRlbnQsbGV2ZWxzPWMoIlNwbGVlbi1NIiwiU3BsZWVuLU1QIiwiU3BsZWVuLWN0cmwiLCJTcGxlZW4tUCIpKQojbGV2ZWxzKENEOHN1YikKYGBgCgpgYGB7cn0KRG90UGxvdChDRDhzdWIsIGRvdC5zY2FsZSA9IDgsZmVhdHVyZXMgPSBjKCJUY3JnLUMxIiwiVHJkYyIsIlRyYmMyIiwiVHJhYyIsImVZRlAiKSApICsgc2NhbGVfY29sb3VyX2dyYWRpZW50Mihsb3cgPSAic3RlZWxibHVlIiwgbWlkID0gIndoaXRlIiwgaGlnaCA9ICJyZWQiKSsgZ2d0aXRsZSgiQ0Q4IG1lbW9yeSBhbmQgZWZmZWN0b3IgY2x1c3RlcnMiKQpgYGAKZXlGUCBuZWdhdGl2ZSBhcmUgY29taW5nIGZyb20gTXljIGFuZCBNeWMgUHRlbiBkZWwgbWljZSBhbmQgYXJlIFRnZCBjZWxscy4KCiNTZXNzaW9uIEluZm8KYGBge3J9CnNlc3Npb25JbmZvKCkKYGBgCg==